Updated gdc-psyfork with latest (NPOTB).
authorNicholas Hastings <skamonkey@gmail.com>
Tue Jul 03 10:27:27 2012 -0400 (2012-07-03)
changeset 3574b51285ca203f
parent 3573 440c51204096
child 3575 664499cf4a2f
Updated gdc-psyfork with latest (NPOTB).
tools/gdc-psyfork/GameConfigs.cpp
tools/gdc-psyfork/GameConfigs.h
tools/gdc-psyfork/MemoryUtils.cpp
tools/gdc-psyfork/MemoryUtils.h
tools/gdc-psyfork/example-scripts/gdc_cstrike.sh
tools/gdc-psyfork/gdc.cpp
tools/gdc-psyfork/gdc.h
tools/gdc-psyfork/symbols.txt
     1.1 --- a/tools/gdc-psyfork/GameConfigs.cpp	Tue Jul 03 07:51:12 2012 -0400
     1.2 +++ b/tools/gdc-psyfork/GameConfigs.cpp	Tue Jul 03 10:27:27 2012 -0400
     1.3 @@ -45,6 +45,7 @@
     1.4  #define PSTATE_GAMEDEFS_CRC				9
     1.5  #define PSTATE_GAMEDEFS_CRC_BINARY		10
     1.6  #define PSTATE_GAMEDEFS_CUSTOM			11
     1.7 +#define PSTATE_GAMEDEFS_OPTIONS			12
     1.8  
     1.9  #define WIN 0
    1.10  #define LIN 1
    1.11 @@ -134,6 +135,10 @@
    1.12  			{
    1.13  				m_ParseState = PSTATE_GAMEDEFS_KEYS;
    1.14  			}
    1.15 +			else if (strcmp(name, "Options") == 0)
    1.16 +			{
    1.17 +				m_ParseState = PSTATE_GAMEDEFS_OPTIONS;
    1.18 +			}
    1.19  			else if ((strcmp(name, "#supported") == 0) && (strcmp(m_Game, "#default") == 0))
    1.20  			{
    1.21  				m_ParseState = PSTATE_GAMEDEFS_SUPPORTED;
    1.22 @@ -206,6 +211,8 @@
    1.23  		}
    1.24  	} else if (m_ParseState == PSTATE_GAMEDEFS_KEYS) {
    1.25  		m_Keys.replace(key, m_pStrings->AddString(value));
    1.26 +	} else if (m_ParseState == PSTATE_GAMEDEFS_OPTIONS) {
    1.27 +		m_Options.replace(key, m_pStrings->AddString(value));
    1.28  	} else if (m_ParseState == PSTATE_GAMEDEFS_SUPPORTED) {
    1.29  		if (strcmp(key, "game") == 0)
    1.30  		{
    1.31 @@ -289,6 +296,7 @@
    1.32  		}
    1.33  	case PSTATE_GAMEDEFS_KEYS:
    1.34  	case PSTATE_GAMEDEFS_OFFSETS:
    1.35 +	case PSTATE_GAMEDEFS_OPTIONS:
    1.36  		{
    1.37  			m_ParseState = PSTATE_GAMEDEFS;
    1.38  			break;
    1.39 @@ -471,6 +479,7 @@
    1.40  	m_Offsets.clear();
    1.41  	m_Sigs.clear();
    1.42  	m_Keys.clear();
    1.43 +	m_Options.clear();
    1.44  
    1.45  	char path[PLATFORM_MAX_PATH];
    1.46  
    1.47 @@ -557,6 +566,14 @@
    1.48  	return m_pStrings->GetString(*pkey);
    1.49  }
    1.50  
    1.51 +const char *CGameConfig::GetOptionValue(const char *key)
    1.52 +{
    1.53 +	int *pkey;
    1.54 +	if ((pkey = m_Options.retrieve(key)) == NULL)
    1.55 +		return NULL;
    1.56 +	return m_pStrings->GetString(*pkey);
    1.57 +}
    1.58 +
    1.59  list<Offset> CGameConfig::GetOffsets() { return m_Offsets; }
    1.60  list<Sig> CGameConfig::GetSigs() { return m_Sigs; }
    1.61  
     2.1 --- a/tools/gdc-psyfork/GameConfigs.h	Tue Jul 03 07:51:12 2012 -0400
     2.2 +++ b/tools/gdc-psyfork/GameConfigs.h	Tue Jul 03 10:27:27 2012 -0400
     2.3 @@ -201,6 +201,7 @@
     2.4  	SMCResult ReadSMC_LeavingSection(const SMCStates *states);
     2.5  public: //IGameConfig
     2.6  	const char *GetKeyValue(const char *key);
     2.7 +	const char *GetOptionValue(const char *key);
     2.8  	bool GetOffset(const char *key, int *value);
     2.9  	SendProp *GetSendProp(const char *key);
    2.10  	bool GetMemSig(const char *key, void **addr);
    2.11 @@ -218,6 +219,7 @@
    2.12  	list<Sig> m_Sigs;
    2.13  //	map<const char*,const char*,cmp_str> m_Keys;
    2.14  	KTrie<int> m_Keys;
    2.15 +	KTrie<int> m_Options;
    2.16  	unsigned int m_RefCount;
    2.17  	/* Parse states */
    2.18  	int m_ParseState;
     3.1 --- a/tools/gdc-psyfork/MemoryUtils.cpp	Tue Jul 03 07:51:12 2012 -0400
     3.2 +++ b/tools/gdc-psyfork/MemoryUtils.cpp	Tue Jul 03 10:27:27 2012 -0400
     3.3 @@ -67,20 +67,27 @@
     3.4  #endif
     3.5  }
     3.6  
     3.7 -void *MemoryUtils::FindPatternInFile(int fd, const char *pattern, size_t len)
     3.8 +void *MemoryUtils::FindPatternInFile(int fd, const char *pattern, size_t len, int &matches, bool &atFuncStart)
     3.9  {
    3.10  	size_t size;
    3.11  	size = lseek (fd , 0 , SEEK_END);
    3.12 +	
    3.13 +	matches = 0;
    3.14 +	// TODO: fix this
    3.15 +	atFuncStart = true;
    3.16  
    3.17  	lseek(fd, 0, SEEK_SET);
    3.18  
    3.19  	void *map;
    3.20 -	char *ptr, *end;
    3.21 +	char *ptr, *start, *end;
    3.22  	bool found = true;
    3.23  	map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
    3.24  
    3.25  	ptr = (char *)map;
    3.26 +	start = ptr;
    3.27  	end = ptr + size;
    3.28 +	
    3.29 +	void *firstMatch = NULL;
    3.30  
    3.31  	while (ptr < end)
    3.32  	{
    3.33 @@ -95,19 +102,49 @@
    3.34  		}
    3.35  
    3.36  		if (found)
    3.37 -			return ptr;
    3.38 +		{
    3.39 +			if( !firstMatch )
    3.40 +			{
    3.41 +				firstMatch = ptr;
    3.42 +				if( ptr - start >= 1 )
    3.43 +				{
    3.44 +					unsigned char oneBack = *(unsigned char*)((intptr_t)ptr - 1);
    3.45 +					if( oneBack != 0xC3 && oneBack != 0xCB && oneBack != 0xCC )
    3.46 +					{
    3.47 +						if( ptr - start >= 3 )
    3.48 +						{
    3.49 +							unsigned char threeBack = *(unsigned char*)((intptr_t)ptr - 3);
    3.50 +							if( threeBack != 0xCA && threeBack != 0xC2 )
    3.51 +							{
    3.52 +								atFuncStart = false;
    3.53 +							}
    3.54 +						}
    3.55 +						else
    3.56 +						{
    3.57 +							atFuncStart = false;
    3.58 +						}
    3.59 +					}
    3.60 +				}
    3.61 +			}
    3.62 +			
    3.63 +			++matches;
    3.64 +		}
    3.65  
    3.66 -		ptr++;
    3.67 +		++ptr;
    3.68  	}
    3.69  
    3.70 -	return NULL;
    3.71 +	return firstMatch;
    3.72  }
    3.73  
    3.74 -void *MemoryUtils::FindPattern(const void *libPtr, const char *pattern, size_t len)
    3.75 +void *MemoryUtils::FindPattern(const void *libPtr, const char *pattern, size_t len, int &matches, bool &atFuncStart)
    3.76  {
    3.77  	DynLibInfo lib;
    3.78  	bool found;
    3.79  	char *ptr, *end;
    3.80 +	
    3.81 +	matches = 0;
    3.82 +	// TODO: fix this
    3.83 +	atFuncStart = true;
    3.84  
    3.85  	memset(&lib, 0, sizeof(DynLibInfo));
    3.86  
    3.87 @@ -115,7 +152,8 @@
    3.88  	{
    3.89  		return NULL;
    3.90  	}
    3.91 -
    3.92 +	
    3.93 +	void *firstMatch = NULL;
    3.94  	ptr = reinterpret_cast<char *>(lib.baseAddress);
    3.95  	end = ptr + lib.memorySize - 1;
    3.96  
    3.97 @@ -132,12 +170,17 @@
    3.98  		}
    3.99  
   3.100  		if (found)
   3.101 -			return ptr;
   3.102 +		{
   3.103 +			if( !firstMatch )
   3.104 +				firstMatch = ptr;
   3.105 +			
   3.106 +			++matches;
   3.107 +		}
   3.108  
   3.109 -		ptr++;
   3.110 +		++ptr;
   3.111  	}
   3.112  
   3.113 -	return NULL;
   3.114 +	return firstMatch;
   3.115  }
   3.116  
   3.117  void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
     4.1 --- a/tools/gdc-psyfork/MemoryUtils.h	Tue Jul 03 07:51:12 2012 -0400
     4.2 +++ b/tools/gdc-psyfork/MemoryUtils.h	Tue Jul 03 10:27:27 2012 -0400
     4.3 @@ -64,11 +64,11 @@
     4.4  	MemoryUtils();
     4.5  	~MemoryUtils();
     4.6  public: // IMemoryUtils
     4.7 -	void *FindPattern(const void *libPtr, const char *pattern, size_t len);
     4.8 +	void *FindPattern(const void *libPtr, const char *pattern, size_t len, int &matches, bool &atFuncStart);
     4.9  	void *ResolveSymbol(void *handle, const char *symbol);
    4.10  	const char *ResolveAddr(void *handle, void *addr);
    4.11  public:
    4.12 -	void *FindPatternInFile(int fd, const char *pattern, size_t len);
    4.13 +	void *FindPatternInFile(int fd, const char *pattern, size_t len, int &matches, bool &atFuncStart);
    4.14  	bool GetLibraryInfo(const void *libPtr, DynLibInfo &lib);
    4.15  #if defined PLATFORM_LINUX || defined PLATFORM_APPLE
    4.16  private:
     5.1 --- a/tools/gdc-psyfork/example-scripts/gdc_cstrike.sh	Tue Jul 03 07:51:12 2012 -0400
     5.2 +++ b/tools/gdc-psyfork/example-scripts/gdc_cstrike.sh	Tue Jul 03 10:27:27 2012 -0400
     5.3 @@ -22,7 +22,7 @@
     5.4  gamedata_files=(
     5.5  	"sdktools.games/game.cstrike.txt"
     5.6  	"sdktools.games/engine.ep2valve.txt"
     5.7 -	"sm-cstrike.games.txt"
     5.8 +	"sm-cstrike.games/game.css.txt"
     5.9  )
    5.10  
    5.11  # Is game a 2006/2007 "mod" ?
     6.1 --- a/tools/gdc-psyfork/gdc.cpp	Tue Jul 03 07:51:12 2012 -0400
     6.2 +++ b/tools/gdc-psyfork/gdc.cpp	Tue Jul 03 10:27:27 2012 -0400
     6.3 @@ -3,6 +3,7 @@
     6.4  #include <dlfcn.h>
     6.5  #include <fcntl.h>
     6.6  #include <math.h>
     6.7 +#include <iostream>
     6.8  #include "gdc.h"
     6.9  #include "GameConfigs.h"
    6.10  #include "MemoryUtils.h"
    6.11 @@ -16,6 +17,11 @@
    6.12  char *wgame_binary = NULL;
    6.13  char *wengine_binary = NULL;
    6.14  
    6.15 +inline bool IsDigit( char c )
    6.16 +{
    6.17 +	return c < 58 && c > 47;
    6.18 +}
    6.19 +
    6.20  int main(int argc, char **argv)
    6.21  {
    6.22  	char *gamedata = NULL;
    6.23 @@ -125,26 +131,6 @@
    6.24  		return 0;
    6.25  	}
    6.26  
    6.27 -	const char *vtsym = symbols.GetKeyValue("vtsym");
    6.28 -	if (!vtsym)
    6.29 -	{
    6.30 -		printf("Couldn't find vtsym\n");
    6.31 -		return 0;
    6.32 -	}
    6.33 -
    6.34 -	void **vt = (void**) mu.ResolveSymbol(ghandle, vtsym);
    6.35 -	if (!vt)
    6.36 -	{
    6.37 -		printf("Couldn't find vtable %s\n", vtsym);
    6.38 -		dlclose(ghandle);
    6.39 -		dlclose(ehandle);
    6.40 -		close(wgfile);
    6.41 -		close(wefile);
    6.42 -
    6.43 -		return 0;
    6.44 -	}
    6.45 -
    6.46 -
    6.47  	for (list<Offset>::iterator it = gc.m_Offsets.begin(); it != gc.m_Offsets.end(); it++)
    6.48  	{
    6.49  		if (debug)
    6.50 @@ -155,34 +141,60 @@
    6.51  		const char *symbol = symbols.GetKeyValue(it->name);
    6.52  		if (symbol)
    6.53  		{
    6.54 +			char symvt[128] = "_ZTV";
    6.55 +			bool bGotFirstNumbers = false;
    6.56 +			bool bLastNumberDigit = false;
    6.57 +			unsigned int symlen = strlen(symbol);
    6.58 +			unsigned int pos = strlen(symvt);
    6.59 +			
    6.60 +			for ( unsigned int i = 0; i < symlen && pos < (sizeof(symvt)-1); ++i )
    6.61 +			{
    6.62 +				bool isDigit = IsDigit( symbol[i] );
    6.63 +				if( !isDigit && bLastNumberDigit )
    6.64 +				{
    6.65 +					bGotFirstNumbers = true;
    6.66 +				}
    6.67 +				
    6.68 +				// we're before the class len
    6.69 +				if( !bGotFirstNumbers && !isDigit )
    6.70 +					continue;
    6.71 +				
    6.72 +				// we're at the function name len
    6.73 +				if( bGotFirstNumbers && isDigit )
    6.74 +				{
    6.75 +					symvt[pos] = 0;
    6.76 +					break;
    6.77 +				}
    6.78 +				
    6.79 +				// we're at the class len or class name. we want these
    6.80 +				symvt[pos++] = symbol[i];
    6.81 +				if( isDigit )
    6.82 +				{
    6.83 +					bLastNumberDigit = isDigit;
    6.84 +				}
    6.85 +			}
    6.86 +			symvt[pos] = 0;
    6.87 +			
    6.88  			int newOffset;
    6.89 -			char symvt[128];
    6.90 -			strcpy(symvt, it->name);
    6.91 -			strcat(symvt, "_vt");
    6.92 -			const char *newvtsym = symbols.GetKeyValue(symvt);
    6.93 -			if (newvtsym && newvtsym[0])
    6.94 +			if (symvt[0])
    6.95  			{
    6.96 -				void **newvt = (void**) mu.ResolveSymbol(ghandle, newvtsym);
    6.97 +				void **newvt = (void**) mu.ResolveSymbol(ghandle, symvt);
    6.98  			        if (!newvt)
    6.99  				{
   6.100 -					printf("O: %-22s - can't find, skipping\n", symvt);
   6.101 +					printf("? O: %-22s - can't find, skipping\n", symvt);
   6.102  					continue;
   6.103  				}
   6.104  
   6.105  				newOffset = findVFunc(ghandle, newvt, symbol);
   6.106  			}
   6.107 -			else
   6.108 -			{
   6.109 -				newOffset = findVFunc(ghandle, vt, symbol);
   6.110 -			}
   6.111  
   6.112  			if (newOffset == it->lin)
   6.113  			{
   6.114 -				printf("O: %-22s - GOOD.    current [ w: %3d, l: %3d ].\n", it->name, it->win, it->lin);
   6.115 +				printf("  O: %-22s - GOOD.    current [ w: %3d, l: %3d ].\n", it->name, it->win, it->lin);
   6.116  			}
   6.117  			else
   6.118  			{
   6.119 -				printf("O: %-22s - CHANGED. old [ w: %3d, l: %3d ]. new [ w: %3d, l: %3d ].\n",
   6.120 +				printf("! O: %-22s - CHANGED. old [ w: %3d, l: %3d ]. new [ w: %3d, l: %3d ].\n",
   6.121  					it->name,
   6.122  					it->win, it->lin,
   6.123  					newOffset - (it->lin - it->win), newOffset
   6.124 @@ -191,7 +203,7 @@
   6.125  		}
   6.126  		else // !symbol
   6.127  		{
   6.128 -			printf("O: %-22s - no Linux symbol, skipping\n", it->name);
   6.129 +			printf("  O: %-22s - no Linux symbol, skipping\n", it->name);
   6.130  		}
   6.131  	}
   6.132  
   6.133 @@ -210,7 +222,7 @@
   6.134  		bool hasWindows = (winSymbol && winSymbol[0]);
   6.135  		if (!hasLinux && !hasWindows)
   6.136  		{
   6.137 -			printf("S: %-22s - hasn't linux nor windows data, skipping\n", it->name);
   6.138 +			printf("  S: %-22s - hasn't linux nor windows data, skipping\n", it->name);
   6.139  			continue;
   6.140  		}
   6.141  		
   6.142 @@ -228,16 +240,17 @@
   6.143  		}
   6.144  		else
   6.145  		{
   6.146 -			printf("S: %-22s - isn't from server nor engine, skipping\n", it->name);
   6.147 +			printf("  S: %-22s - isn't from server nor engine, skipping\n", it->name);
   6.148  			continue;
   6.149  		}
   6.150  		
   6.151 -		bool foundLinux   = (!hasLinux   || checkSigStringL(linHandle, linSymbol));
   6.152 -		bool foundWindows = (!hasWindows || checkSigStringW(winFile,   winSymbol));
   6.153 +		int linuxMatches = 0, windowsMatches = 0;
   6.154 +		if( hasLinux )
   6.155 +			linuxMatches = checkSigStringL(linHandle, linSymbol);
   6.156 +		if( hasWindows )
   6.157 +			windowsMatches = checkSigStringW(winFile,   winSymbol);
   6.158  			
   6.159 -		// Prepare for ternery ABUSE
   6.160 -		
   6.161 -		if (foundLinux && foundWindows)
   6.162 +		if (linuxMatches == 1 && windowsMatches == 1)
   6.163  		{
   6.164  			// too much clutter to print current data if it matches anyway, unlike with offsets
   6.165  			/*
   6.166 @@ -248,42 +261,86 @@
   6.167  				linSymbol ? linSymbol : ""
   6.168  				);
   6.169  			*/
   6.170 -			printf("S: %-22s (%s) - GOOD.\n",
   6.171 +			printf("  S: %-22s (%s) - w: GOOD     - l: GOOD    \n",
   6.172  				it->name,
   6.173  				(it->lib == Server) ? "server" : "engine"
   6.174  				);
   6.175  		}
   6.176  		else
   6.177  		{
   6.178 -			// extra \n at end is intentional to add buffer after possibly long sigs
   6.179 -			printf("S: %-22s (%s) - w: %s - l: %s\n%s%s%s%s%s%s%s%s\n",
   6.180 -					it->name,
   6.181 -					(it->lib == Server) ? "server" : "engine",
   6.182 -					hasWindows ? (foundWindows ? "GOOD" : "CHANGED") : "UNKNOWN",
   6.183 -					hasLinux   ? (foundLinux   ? "GOOD" : "CHANGED") : "UNKNOWN",
   6.184 -					
   6.185 -					hasWindows ? "\tcurrent - w: " : "",
   6.186 -					(hasWindows && foundWindows) ? "    (found) \"" : (hasWindows ? "(NOT found) \"" : ""),
   6.187 -					(hasWindows && winSymbol)  ? winSymbol : "",
   6.188 -					hasWindows ? "\"\n" : "",
   6.189 -					
   6.190 -					hasLinux ? "\tcurrent - l: " : "",
   6.191 -					(hasLinux && foundLinux) ? "    (found) \"" : (hasLinux ? "(NOT found) \"" : ""),
   6.192 -					(hasLinux && linSymbol)  ? linSymbol : "",
   6.193 -					hasLinux ? "\"\n" : ""
   6.194 +			char winStatus[16];
   6.195 +			// right now the only option is to ignore
   6.196 +			const char *options = symbols.GetOptionValue(it->name);
   6.197 +			bool allowMulti = ( options && strstr(options, "allowmultiple") != NULL );
   6.198 +			bool allowMidfunc = ( options && strstr(options, "allowmidfunc") != NULL );
   6.199 +			
   6.200 +			bool bWinGood = false;
   6.201 +			if( !hasWindows ) {
   6.202 +				snprintf( winStatus, sizeof(winStatus), "UNKNOWN" );
   6.203 +			}
   6.204 +			else if( windowsMatches == -1 && !allowMidfunc) {
   6.205 +				snprintf( winStatus, sizeof(winStatus), "MIDFUNC" );
   6.206 +			}
   6.207 +			else if( windowsMatches == 0 ) {
   6.208 +				snprintf( winStatus, sizeof(winStatus), "NOTFOUND" );
   6.209 +			}
   6.210 +			else if( windowsMatches > 1 && !allowMulti) {
   6.211 +				snprintf( winStatus, sizeof(winStatus), "MULTIPLE" );
   6.212 +			}
   6.213 +			else {
   6.214 +				bWinGood = true;
   6.215 +				snprintf( winStatus, sizeof(winStatus), "GOOD" );
   6.216 +			}
   6.217 +			
   6.218 +			char linStatus[16];
   6.219 +			bool bLinGood = false;
   6.220 +			if( !hasLinux ) {
   6.221 +				snprintf( linStatus, sizeof(linStatus), "UNKNOWN" );
   6.222 +			}
   6.223 +			else if( linuxMatches == 0 ) {
   6.224 +				snprintf( linStatus, sizeof(linStatus), "NOTFOUND" );
   6.225 +			}
   6.226 +			else if( linuxMatches == 1 ) {
   6.227 +				bLinGood = true;
   6.228 +				snprintf( linStatus, sizeof(linStatus), "GOOD" );
   6.229 +			}
   6.230 +			else {
   6.231 +				snprintf( linStatus, sizeof(linStatus), "CHECK" );
   6.232 +			}
   6.233 +			
   6.234 +			bool showWinExtra = (hasWindows && !bWinGood);
   6.235 +			bool showLinExtra = ( ( hasLinux && !bLinGood ) || showWinExtra );
   6.236 +			
   6.237 +			printf("%s S: %-22s (%s)", (showWinExtra || showLinExtra) ? "!" : " ", it->name, (it->lib == Server) ? "server" : "engine" );
   6.238 +				printf(" - w: %-8s - l: %-8s\n", winStatus, linStatus );
   6.239 +			
   6.240 +			if( showWinExtra || showLinExtra )
   6.241 +				printf( "!    current:\n" );
   6.242 +			
   6.243 +			if( showWinExtra )
   6.244 +			{
   6.245 +				printf("!    w: \"%s\"\n",
   6.246 +					winSymbol ? winSymbol : ""
   6.247  					);
   6.248 +			}
   6.249  			
   6.250 +			if( showLinExtra )
   6.251 +			{
   6.252 +				// extra \n at end is intentional to add buffer after possibly long sigs
   6.253 +				printf("!    l: \"%s\"\n\n",
   6.254 +					linSymbol ? linSymbol : ""
   6.255 +					);
   6.256 +			}			
   6.257  		}
   6.258 -		
   6.259 -		//  j/k, no way that anyone could have been prepared for that
   6.260  	}
   6.261  
   6.262  	return 0;
   6.263  }
   6.264  
   6.265 -bool checkSigStringW(int file, const char* symbol)
   6.266 +int checkSigStringW(int file, const char* symbol)
   6.267  {
   6.268 -	void *addr = NULL;
   6.269 +	int matches = 0;
   6.270 +	bool atFuncStart = true;
   6.271  	bool isAt = (symbol[0] == '@');
   6.272  	// we can't support this on windows from here
   6.273  	if (isAt)
   6.274 @@ -294,23 +351,25 @@
   6.275  
   6.276  	if (real_bytes >= 1)
   6.277  	{
   6.278 -		addr = mu.FindPatternInFile(file, (char*)real_sig, real_bytes);
   6.279 +		mu.FindPatternInFile(file, (char*)real_sig, real_bytes, matches, atFuncStart);
   6.280  	}
   6.281  
   6.282 -	if (addr)
   6.283 -		return true;
   6.284 +	if( !atFuncStart )
   6.285 +		return -1;
   6.286  	
   6.287 -	return false;
   6.288 +	return matches;
   6.289  }
   6.290  
   6.291 -bool checkSigStringL(void *handle, const char* symbol)
   6.292 +int checkSigStringL(void *handle, const char* symbol)
   6.293  {
   6.294 -	void *addr = NULL;
   6.295  	bool isAt = (symbol[0] == '@');
   6.296 +	int matches = 0;
   6.297 +	bool dummy;
   6.298  	
   6.299  	if (isAt)
   6.300  	{
   6.301 -		addr = mu.ResolveSymbol(handle, symbol + 1);
   6.302 +		if( mu.ResolveSymbol(handle, symbol + 1) )
   6.303 +			matches = 1;
   6.304  	}
   6.305  	else
   6.306  	{
   6.307 @@ -319,14 +378,11 @@
   6.308  
   6.309  		if (real_bytes >= 1)
   6.310  		{
   6.311 -			addr = mu.FindPattern(handle, (char*)real_sig, real_bytes);
   6.312 +			mu.FindPattern(handle, (char*)real_sig, real_bytes, matches, dummy);
   6.313  		}
   6.314  	}
   6.315  
   6.316 -	if (addr)
   6.317 -		return true;
   6.318 -	
   6.319 -	return false;
   6.320 +	return matches;
   6.321  }
   6.322  
   6.323  /* 
     7.1 --- a/tools/gdc-psyfork/gdc.h	Tue Jul 03 07:51:12 2012 -0400
     7.2 +++ b/tools/gdc-psyfork/gdc.h	Tue Jul 03 10:27:27 2012 -0400
     7.3 @@ -12,8 +12,8 @@
     7.4  int findFuncPos(const char* sym);
     7.5  int findVFunc(void *handle, void **vt, const char *symbol);
     7.6  
     7.7 -bool checkSigStringW(int file, const char* symbol);
     7.8 -bool checkSigStringL(void* handle, const char* symbol);
     7.9 +int checkSigStringW(int file, const char* symbol);
    7.10 +int checkSigStringL(void* handle, const char* symbol);
    7.11  
    7.12  size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
    7.13  size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr);
     8.1 --- a/tools/gdc-psyfork/symbols.txt	Tue Jul 03 07:51:12 2012 -0400
     8.2 +++ b/tools/gdc-psyfork/symbols.txt	Tue Jul 03 10:27:27 2012 -0400
     8.3 @@ -1,30 +1,28 @@
     8.4  "Games"
     8.5  {
     8.6 +	/*
     8.7 +	 * "Keys" are used to map gamedata offset names to linux symbol.
     8.8 +	 * "Options" are used to mark validation options for windows signatures.
     8.9 +	 *     Current valid options are:
    8.10 +	 *         allowmultiple - don't warn if multiple matches are found
    8.11 +	 *         allowmidfunc  - don't warn if signature does not match the
    8.12 +	 *                         start of a function.
    8.13 +	 *     Multiple options can be specified, separating them with a comma.
    8.14 +	 *         ie. "allowmultiple,allowmidfunc"
    8.15 +	 */
    8.16 +	 
    8.17  	"#default"
    8.18  	{
    8.19  		"Keys"
    8.20  		{
    8.21 -			"vtsym"		"_ZTV11CBaseEntity"
    8.22 +			// SDKTools
    8.23  			"GiveNamedItem"		"_ZN11CBasePlayer13GiveNamedItemEPKci"
    8.24 -			"GiveNamedItem_vt"	"_ZTV11CBasePlayer"
    8.25 -			
    8.26  			"RemovePlayerItem"		"_ZN11CBasePlayer16RemovePlayerItemEP17CBaseCombatWeapon"
    8.27 -			"RemovePlayerItem_vt"	"_ZTV11CBasePlayer"
    8.28 -			
    8.29  			"Weapon_GetSlot"		"_ZNK20CBaseCombatCharacter14Weapon_GetSlotEi"
    8.30 -			"Weapon_GetSlot_vt"		"_ZTV20CBaseCombatCharacter"
    8.31 -			
    8.32  			"Ignite"			"_ZN14CBaseAnimating6IgniteEfbfb"
    8.33 -			"Ignite_vt"			"_ZTV14CBaseAnimating"
    8.34 -			
    8.35  			"Extinguish" 			"_ZN14CBaseAnimating10ExtinguishEv"
    8.36 -			"Extinguish_vt" 		"_ZTV14CBaseAnimating"
    8.37 -			
    8.38  			"Teleport"			"_ZN11CBaseEntity8TeleportEPK6VectorPK6QAngleS2_"
    8.39 -			
    8.40  			"CommitSuicide" 	"_ZN11CBasePlayer13CommitSuicideEbb"
    8.41 -			"CommitSuicide_vt"	"_ZTV11CBasePlayer"
    8.42 -			
    8.43  			"GetVelocity"				"_ZN11CBaseEntity11GetVelocityEP6VectorS1_"
    8.44  			"EyeAngles"					"_ZN11CBasePlayer9EyeAnglesEv"
    8.45  			"DispatchKeyValue"			"_ZN11CBaseEntity8KeyValueEPKcS1_"
    8.46 @@ -32,14 +30,9 @@
    8.47  			"DispatchKeyValueVector"	"_ZN11CBaseEntity8KeyValueEPKcRK6Vector"
    8.48  			"SetEntityModel"			"_ZN11CBaseEntity8SetModelEPKc"
    8.49  			"AcceptInput"				"_ZN11CBaseEntity11AcceptInputEPKcPS_S2_9variant_ti"
    8.50 -			
    8.51  			"WeaponEquip"		"_ZN11CBasePlayer12Weapon_EquipEP17CBaseCombatWeapon"
    8.52 -			"WeaponEquip_vt"	"_ZTV20CBaseCombatCharacter"
    8.53 -			
    8.54  			"Activate"			"_ZN11CBaseEntity8ActivateEv"
    8.55 -			
    8.56  			"PlayerRunCmd"		"_ZN11CBasePlayer16PlayerRunCommandEP8CUserCmdP11IMoveHelper"
    8.57 -			"PlayerRunCmd_vt"	"_ZTV11CBasePlayer"
    8.58  			
    8.59  			// SDKHooks
    8.60  			"EndTouch"			"_ZN11CBaseEntity8EndTouchEPS_"
    8.61 @@ -47,11 +40,8 @@
    8.62  			"GroundEntChanged"	"_ZN11CBaseEntity35NetworkStateChanged_m_hGroundEntityEv"
    8.63  			"OnTakeDamage"		"_ZN11CBaseEntity12OnTakeDamageERK15CTakeDamageInfo"
    8.64  			"PreThink"			"_ZN11CBasePlayer8PreThinkEv"
    8.65 -			"PreThink_vt"		"_ZTV11CBasePlayer"
    8.66  			"PostThink"			"_ZN11CBasePlayer9PostThinkEv"
    8.67 -			"PostThink_vt"		"_ZTV11CBasePlayer"
    8.68  			"Reload"			"_ZN17CBaseCombatWeapon6ReloadEv"
    8.69 -			"Reload_vt"			"_ZTV17CBaseCombatWeapon"
    8.70  			"SetTransmit"		"_ZN11CBaseEntity11SetTransmitEP18CCheckTransmitInfob"
    8.71  			"ShouldCollide"		"_ZNK11CBaseEntity13ShouldCollideEii"
    8.72  			"Spawn"				"_ZN11CBaseEntity5SpawnEv"
    8.73 @@ -63,15 +53,33 @@
    8.74  			"Use"				"_ZN11CBaseEntity3UseEPS_S0_8USE_TYPEf"
    8.75  			"VPhysicsUpdate"	"_ZN11CBaseEntity14VPhysicsUpdateEP14IPhysicsObject"
    8.76  			"Weapon_CanSwitchTo"	"_ZN20CBaseCombatCharacter18Weapon_CanSwitchToEP17CBaseCombatWeapon"
    8.77 -			"Weapon_CanSwitchTo_vt"	"_ZTV20CBaseCombatCharacter"
    8.78  			"Weapon_CanUse"		"_ZN20CBaseCombatCharacter13Weapon_CanUseEP17CBaseCombatWeapon"
    8.79 -			"Weapon_CanUse_vt"	"_ZTV20CBaseCombatCharacter"
    8.80  			"Weapon_Drop"		"_ZN20CBaseCombatCharacter11Weapon_DropEP17CBaseCombatWeaponPK6VectorS4_"
    8.81 -			"Weapon_Drop_vt"	"_ZTV20CBaseCombatCharacter"
    8.82  			"Weapon_Equip"		"_ZN11CBasePlayer12Weapon_EquipEP17CBaseCombatWeapon"
    8.83 -			"Weapon_Equip_vt"	"_ZTV20CBaseCombatCharacter"
    8.84  			"Weapon_Switch"		"_ZN20CBaseCombatCharacter13Weapon_SwitchEP17CBaseCombatWeaponi"
    8.85 -			"Weapon_Switch_vt"	"_ZTV20CBaseCombatCharacter"
    8.86 +			
    8.87 +			// CEntity extras
    8.88 +			"FVisible"			"_ZN20CBaseCombatCharacter8FVisibleEP11CBaseEntityiPS1_"
    8.89 +			"VPhysicsTakeDamage"	"_ZN11CBaseEntity18VPhysicsTakeDamageERK15CTakeDamageInfo"
    8.90 +			"VPhysicsGetObjectList"	"_ZN11CBaseEntity21VPhysicsGetObjectListEPP14IPhysicsObjecti"
    8.91 +			"GetClientEyeAngles"	"_ZN11CBaseEntity9EyeAnglesEv"
    8.92 +			"WeaponSwitch"		"_ZN20CBaseCombatCharacter13Weapon_SwitchEP17CBaseCombatWeaponi"
    8.93 +			"CanSpeakVoiceCommand"	"_ZN22CBaseMultiplayerPlayer20CanSpeakVoiceCommandEv"
    8.94 +			"IsReadyToSpawn"		"_ZN11CBasePlayer14IsReadyToSpawnEv"
    8.95 +			"OnTakeDamage_Alive"	"_ZN20CBaseCombatCharacter18OnTakeDamage_AliveERK15CTakeDamageInfo"
    8.96 +			"Jump"				"_ZN11CBasePlayer4JumpEv"
    8.97 +			"ProcessUserCmds"		"_ZN11CBasePlayer15ProcessUsercmdsEP8CUserCmdiiib"
    8.98 +			"GetSoundEmissionOrigin"	"_ZNK11CBaseEntity22GetSoundEmissionOriginEv"
    8.99 +			"GetServerClass"	"_ZN11CBaseEntity14GetServerClassEv"
   8.100 +			"StudioFrameAdvance"	"_ZN14CBaseAnimating18StudioFrameAdvanceEv"
   8.101 +			"ShouldGib"		"_ZN20CBaseCombatCharacter9ShouldGibERK15CTakeDamageInfo"
   8.102 +			"GetRadius"		"_ZN13CTFBaseRocket9GetRadiusEv"
   8.103 +			"DeflectPlayer"		"_ZN13CTFWeaponBase13DeflectPlayerEP9CTFPlayerS1_R6VectorS3_S3_"
   8.104 +		}
   8.105 +		
   8.106 +		"Options"
   8.107 +		{
   8.108 +			"CreateGameRulesObject"		"allowmultiple,allowmidfunc"
   8.109  		}
   8.110  	}
   8.111  	
   8.112 @@ -82,6 +90,7 @@
   8.113  			"engine"	"orangebox_valve"
   8.114  			"engine"	"left4dead2"
   8.115  			"engine"	"alienswarm"
   8.116 +			"engine"	"csgo"
   8.117  		}
   8.118  		
   8.119  		"Keys"
   8.120 @@ -100,15 +109,10 @@
   8.121  		"Keys"
   8.122  		{
   8.123  			"ForceRespawn"			"_ZN9CTFPlayer12ForceRespawnEv"
   8.124 -			"ForceRespawn_vt"		"_ZTV9CTFPlayer"
   8.125  			"GiveNamedItemTF"		"_ZN9CTFPlayer13GiveNamedItemEPKciP13CEconItemViewb"
   8.126 -			"GiveNamedItemTF_vt"	"_ZTV9CTFPlayer"
   8.127  			"EquipWearable"			"_ZN11CBasePlayer13EquipWearableEP13CEconWearable"
   8.128 -			"EquipWearable_vt"		"_ZTV11CBasePlayer"
   8.129  			"RemoveWearable"		"_ZN11CBasePlayer14RemoveWearableEP13CEconWearable"
   8.130 -			"RemoveWearable_vt"		"_ZTV11CBasePlayer"
   8.131  			"GrenadeDetonate"		"_ZN12CBaseGrenade8DetonateEv"
   8.132 -			"GrenadeDetonate_vt"	"_ZTV12CBaseGrenade"
   8.133  		}
   8.134  	}
   8.135  
   8.136 @@ -117,13 +121,38 @@
   8.137  		"#supported"
   8.138  		{
   8.139  			"engine"	"left4dead"
   8.140 -			"engine"	"left4dead2"
   8.141 +			"game"	"left4dead2"
   8.142  		}
   8.143  
   8.144  		"Keys"
   8.145  		{
   8.146  			"GiveNamedItem"		"_ZN9CCSPlayer13GiveNamedItemEPKci"
   8.147 -			"GiveNamedItem_vt"       "_ZTV9CCSPlayer"
   8.148 +		}
   8.149 +	}
   8.150 +
   8.151 +	"#default"
   8.152 +	{
   8.153 +		"#supported"
   8.154 +		{
   8.155 +			"game"	"nucleardawn"
   8.156 +		}
   8.157 +		"Keys"
   8.158 +		{
   8.159 +			"GiveNamedItem"		"_ZN9CNDPlayer13GiveNamedItemEPKcib"
   8.160 +		}
   8.161 +	}
   8.162 +
   8.163 +	"#default"
   8.164 +	{
   8.165 +		"#supported"
   8.166 +		{
   8.167 +			"engine"	"csgo"
   8.168 +		}
   8.169 +		
   8.170 +		"Keys"
   8.171 +		{
   8.172 +			"Teleport"	"_ZN11CBaseEntity8TeleportEPK6VectorPK6QAngleS2_b"
   8.173 +			"GiveNamedItem"	"_ZN11CBasePlayer13GiveNamedItemEPKcib"
   8.174  		}
   8.175  	}
   8.176  }