extensions/sdktools/vglobals.cpp
author Peace-Maker <januk@freenet.de>
Tue Feb 05 21:45:11 2013 +0000 (2013-02-05)
changeset 3763 336283ba3a38
parent 3627 b6e36874284b
child 3816 31650bb3c7e8
permissions -rw-r--r--
Updated for CS:S sync (r=asherkin).
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
skamonkey@3221
    42
	/*
skamonkey@3221
    43
	 * g_pGameRules
skamonkey@3221
    44
	 *
skamonkey@3221
    45
	 * First try to lookup pointer directly for platforms with symbols.
skamonkey@3221
    46
	 * If symbols aren't present (Windows or stripped Linux/Mac), 
skamonkey@3221
    47
	 * attempt find via CreateGameRulesObject + offset
skamonkey@3221
    48
	 */
faluco@1718
    49
skamonkey@3221
    50
	char *addr;
skamonkey@3221
    51
	if (g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) && addr)
faluco@1718
    52
	{
skamonkey@3221
    53
		g_pGameRules = reinterpret_cast<void **>(addr);
faluco@1718
    54
	}
skamonkey@3221
    55
	else if (g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) && addr)
faluco@1247
    56
	{
skamonkey@3221
    57
		int offset;
skamonkey@3221
    58
		if (!g_pGameConf->GetOffset("g_pGameRules", &offset) || !offset)
skamonkey@3221
    59
		{
skamonkey@3221
    60
			return;
skamonkey@3221
    61
		}
skamonkey@3221
    62
		g_pGameRules = *reinterpret_cast<void ***>(addr + offset);
faluco@1247
    63
	}
faluco@1247
    64
}
faluco@1769
    65
ds@2535
    66
size_t UTIL_StringToSignature(const char *str, char buffer[], size_t maxlength)
ds@1952
    67
{
ds@2535
    68
	size_t real_bytes = 0;
ds@2535
    69
	size_t length = strlen(str);
ds@1952
    70
ds@2535
    71
	for (size_t i=0; i<length; i++)
ds@2535
    72
	{
ds@2535
    73
		if (real_bytes >= maxlength)
ds@2535
    74
		{
ds@2535
    75
			break;
ds@2535
    76
		}
ds@2535
    77
		buffer[real_bytes++] = (unsigned char)str[i];
ds@2535
    78
		if (str[i] == '\\'
ds@2535
    79
			&& str[i+1] == 'x')
ds@2535
    80
		{
ds@2535
    81
			if (i + 3 >= length)
ds@2535
    82
			{
ds@2535
    83
				continue;
ds@2535
    84
			}
ds@2535
    85
			/* Get the hex part */
ds@2535
    86
			char s_byte[3];
ds@2535
    87
			int r_byte;
ds@2535
    88
			s_byte[0] = str[i+2];
ds@2535
    89
			s_byte[1] = str[i+3];
ds@2535
    90
			s_byte[2] = '\n';
ds@2535
    91
			/* Read it as an integer */
ds@2535
    92
			sscanf(s_byte, "%x", &r_byte);
ds@2535
    93
			/* Save the value */
ds@2535
    94
			buffer[real_bytes-1] = (unsigned char)r_byte;
ds@2535
    95
			/* Adjust index */
ds@2535
    96
			i += 3;
ds@2535
    97
		}
ds@2535
    98
	}
ds@2535
    99
ds@2535
   100
	return real_bytes;
ds@2535
   101
}
ds@2535
   102
ds@2535
   103
bool UTIL_VerifySignature(const void *addr, const char *sig, size_t len)
ds@2535
   104
{
ds@2535
   105
	unsigned char *addr1 = (unsigned char *) addr;
ds@2535
   106
	unsigned char *addr2 = (unsigned char *) sig;
ds@2535
   107
ds@2535
   108
	for (size_t i = 0; i < len; i++)
ds@1952
   109
	{
ds@1952
   110
		if (addr2[i] == '*')
ds@1952
   111
			continue;
ds@1952
   112
		if (addr1[i] != addr2[i])
ds@1952
   113
			return false;
ds@1952
   114
	}
ds@1952
   115
ds@1952
   116
	return true;
faluco@1773
   117
}
faluco@1773
   118
faluco@1769
   119
#if defined PLATFORM_WINDOWS
faluco@1769
   120
void GetIServer()
faluco@1769
   121
{
ds@2535
   122
	const char *sigstr;
ds@2535
   123
	char sig[32];
ds@2535
   124
	size_t siglen;
faluco@1769
   125
	int offset;
faluco@1769
   126
	void *vfunc = NULL;
faluco@1769
   127
ds@2858
   128
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
faluco@1769
   129
	/* Get the CreateFakeClient function pointer */
faluco@1769
   130
	if (!(vfunc=SH_GET_ORIG_VFNPTR_ENTRY(engine, &IVEngineServer::CreateFakeClient)))
faluco@1769
   131
	{
faluco@1769
   132
		return;
faluco@1769
   133
	}
faluco@1769
   134
#else
faluco@1769
   135
	/* Get the interface manually */
faluco@1769
   136
	SourceHook::MemFuncInfo info = {true, -1, 0, 0};
faluco@1769
   137
	SourceHook::GetFuncInfo(&IVEngineServer::CreateFakeClient, info);
faluco@1769
   138
faluco@1769
   139
	vfunc = enginePatch->GetOrigFunc(info.vtbloffs, info.vtblindex);
faluco@1769
   140
	if (!vfunc)
faluco@1769
   141
	{
faluco@1769
   142
		void **vtable = *reinterpret_cast<void ***>(enginePatch->GetThisPtr() + info.thisptroffs + info.vtbloffs);
faluco@1769
   143
		vfunc = vtable[info.vtblindex];
faluco@1769
   144
	}
ds@2535
   145
#endif
ds@2535
   146
ds@2535
   147
	/* Get signature string for IVEngineServer::CreateFakeClient() */
ds@2535
   148
	sigstr = g_pGameConf->GetKeyValue("CreateFakeClient_Windows");
ds@2535
   149
ds@2535
   150
	if (!sigstr)
faluco@1773
   151
	{
faluco@1773
   152
		return;
faluco@1773
   153
	}
faluco@1769
   154
ds@2535
   155
	/* Convert signature string to signature bytes */
ds@2535
   156
	siglen = UTIL_StringToSignature(sigstr, sig, sizeof(sig));
ds@2535
   157
ds@2535
   158
	/* Check if we're on the expected function */
ds@2535
   159
	if (!UTIL_VerifySignature(vfunc, sig, siglen))
ds@2535
   160
	{
ds@2535
   161
		return;
ds@2535
   162
	}
ds@2535
   163
ds@2535
   164
	/* Get the offset into CreateFakeClient */
ds@2535
   165
	if (!g_pGameConf->GetOffset("sv", &offset))
ds@2535
   166
	{
ds@2535
   167
		return;
ds@2535
   168
	}
ds@2535
   169
ds@2535
   170
	/* Finally we have the interface we were looking for */
faluco@1769
   171
	iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
faluco@1769
   172
}
faluco@1769
   173
#elif defined PLATFORM_POSIX
faluco@1769
   174
void GetIServer()
faluco@1769
   175
{
faluco@1769
   176
	void *addr;
faluco@1769
   177
	if (!g_pGameConf->GetMemSig("sv", &addr) || !addr)
faluco@1769
   178
	{
faluco@1769
   179
		return;
faluco@1769
   180
	}
faluco@1769
   181
faluco@1773
   182
	iserver = reinterpret_cast<IServer *>(addr);
faluco@1769
   183
}
faluco@1769
   184
#endif
skamonkey@3333
   185
skamonkey@3333
   186
const char *GetDTTypeName(int type)
skamonkey@3333
   187
{
skamonkey@3333
   188
	switch (type)
skamonkey@3333
   189
	{
skamonkey@3333
   190
	case DPT_Int:
skamonkey@3333
   191
		{
skamonkey@3333
   192
			return "integer";
skamonkey@3333
   193
		}
skamonkey@3333
   194
	case DPT_Float:
skamonkey@3333
   195
		{
skamonkey@3333
   196
			return "float";
skamonkey@3333
   197
		}
skamonkey@3333
   198
	case DPT_Vector:
skamonkey@3333
   199
		{
skamonkey@3333
   200
			return "vector";
skamonkey@3333
   201
		}
skamonkey@3333
   202
	case DPT_String:
skamonkey@3333
   203
		{
skamonkey@3333
   204
			return "string";
skamonkey@3333
   205
		}
skamonkey@3333
   206
	case DPT_Array:
skamonkey@3333
   207
		{
skamonkey@3333
   208
			return "array";
skamonkey@3333
   209
		}
skamonkey@3333
   210
	case DPT_DataTable:
skamonkey@3333
   211
		{
skamonkey@3333
   212
			return "datatable";
skamonkey@3333
   213
		}
skamonkey@3333
   214
	default:
skamonkey@3333
   215
		{
skamonkey@3333
   216
			return NULL;
skamonkey@3333
   217
		}
skamonkey@3333
   218
	}
skamonkey@3333
   219
skamonkey@3333
   220
	return NULL;
skamonkey@3333
   221
}