tools/gdc/GameConfigs.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Thu Jul 18 21:07:14 2013 -0400 (2013-07-18)
changeset 3957 fe91589c0458
parent 3129 76208f2e5ef0
permissions -rw-r--r--
Synced gdc-psyfork symbols.txt with live version (NPOTB).
fyrenmoo@3129
     1
/**
fyrenmoo@3129
     2
 * vim: set ts=4 :
fyrenmoo@3129
     3
 * =============================================================================
fyrenmoo@3129
     4
 * SourceMod
fyrenmoo@3129
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
fyrenmoo@3129
     6
 * =============================================================================
fyrenmoo@3129
     7
 *
fyrenmoo@3129
     8
 * This program is free software; you can redistribute it and/or modify it under
fyrenmoo@3129
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
fyrenmoo@3129
    10
 * Free Software Foundation.
fyrenmoo@3129
    11
 * 
fyrenmoo@3129
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
fyrenmoo@3129
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
fyrenmoo@3129
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
fyrenmoo@3129
    15
 * details.
fyrenmoo@3129
    16
 *
fyrenmoo@3129
    17
 * You should have received a copy of the GNU General Public License along with
fyrenmoo@3129
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
fyrenmoo@3129
    19
 *
fyrenmoo@3129
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
fyrenmoo@3129
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
fyrenmoo@3129
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
fyrenmoo@3129
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
fyrenmoo@3129
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
fyrenmoo@3129
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
fyrenmoo@3129
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
fyrenmoo@3129
    27
 * or <http://www.sourcemod.net/license.php>.
fyrenmoo@3129
    28
 *
fyrenmoo@3129
    29
 * Version: $Id$
fyrenmoo@3129
    30
 */
fyrenmoo@3129
    31
fyrenmoo@3129
    32
#include <string.h>
fyrenmoo@3129
    33
#include <stdlib.h>
fyrenmoo@3129
    34
#include "GameConfigs.h"
fyrenmoo@3129
    35
//#include "sm_stringutil.h"
fyrenmoo@3129
    36
//#include "sourcemod.h"
fyrenmoo@3129
    37
//#include "sourcemm_api.h"
fyrenmoo@3129
    38
//#include "HalfLife2.h"
fyrenmoo@3129
    39
//#include "Logger.h"
fyrenmoo@3129
    40
//#include "ShareSys.h"
fyrenmoo@3129
    41
//#include "MemoryUtils.h"
fyrenmoo@3129
    42
//#include "LibrarySys.h"
fyrenmoo@3129
    43
//#include "HandleSys.h"
fyrenmoo@3129
    44
//#include "sm_crc32.h"
fyrenmoo@3129
    45
fyrenmoo@3129
    46
//#if defined PLATFORM_LINUX
fyrenmoo@3129
    47
//#include <dlfcn.h>
fyrenmoo@3129
    48
//#endif
fyrenmoo@3129
    49
fyrenmoo@3129
    50
#define PSTATE_NONE						0
fyrenmoo@3129
    51
#define PSTATE_GAMES					1
fyrenmoo@3129
    52
#define PSTATE_GAMEDEFS					2
fyrenmoo@3129
    53
#define PSTATE_GAMEDEFS_OFFSETS			3
fyrenmoo@3129
    54
#define PSTATE_GAMEDEFS_OFFSETS_OFFSET	4
fyrenmoo@3129
    55
#define PSTATE_GAMEDEFS_KEYS			5
fyrenmoo@3129
    56
#define PSTATE_GAMEDEFS_SUPPORTED		6
fyrenmoo@3129
    57
#define PSTATE_GAMEDEFS_SIGNATURES		7
fyrenmoo@3129
    58
#define PSTATE_GAMEDEFS_SIGNATURES_SIG	8
fyrenmoo@3129
    59
#define PSTATE_GAMEDEFS_CRC				9
fyrenmoo@3129
    60
#define PSTATE_GAMEDEFS_CRC_BINARY		10
fyrenmoo@3129
    61
#define PSTATE_GAMEDEFS_CUSTOM			11
fyrenmoo@3129
    62
fyrenmoo@3129
    63
#define WIN 0
fyrenmoo@3129
    64
#define LIN 1
fyrenmoo@3129
    65
fyrenmoo@3129
    66
#define PLATFORM_NAME				"linux"
fyrenmoo@3129
    67
#define PLATFORM_SERVER_BINARY		"server_i486.so"
fyrenmoo@3129
    68
fyrenmoo@3129
    69
Offset *tempOffset;
fyrenmoo@3129
    70
Sig *tempSig;
fyrenmoo@3129
    71
fyrenmoo@3129
    72
unsigned int s_ServerBinCRC;
fyrenmoo@3129
    73
bool s_ServerBinCRC_Ok = false;
fyrenmoo@3129
    74
fyrenmoo@3129
    75
bool /*CGameConfig::*/DoesGameMatch(const char *value)
fyrenmoo@3129
    76
{
fyrenmoo@3129
    77
	if (strcmp(value, /*m_gdcG*/game) == 0)
fyrenmoo@3129
    78
	{
fyrenmoo@3129
    79
		return true;
fyrenmoo@3129
    80
	}
fyrenmoo@3129
    81
	return false;
fyrenmoo@3129
    82
}
fyrenmoo@3129
    83
fyrenmoo@3129
    84
bool /*CGameConfig::*/DoesEngineMatch(const char *value)
fyrenmoo@3129
    85
{
fyrenmoo@3129
    86
	if (strcmp(value, /*m_gdcE*/engine) == 0)
fyrenmoo@3129
    87
	{
fyrenmoo@3129
    88
		return true;
fyrenmoo@3129
    89
	}
fyrenmoo@3129
    90
	return false;
fyrenmoo@3129
    91
}
fyrenmoo@3129
    92
fyrenmoo@3129
    93
CGameConfig::CGameConfig()//const char *file)//, const char *game, const char *engine)
fyrenmoo@3129
    94
{
fyrenmoo@3129
    95
//	strncopy(m_File, file, sizeof(m_File));
fyrenmoo@3129
    96
//	strncopy(m_gdcGame, game, sizeof(m_gdcGame));
fyrenmoo@3129
    97
//	strncopy(m_gdcEngine, engine, sizeof(m_gdcEngine));
fyrenmoo@3129
    98
	//m_pStrings = new BaseStringTable(512);
fyrenmoo@3129
    99
	m_RefCount = 0;
fyrenmoo@3129
   100
fyrenmoo@3129
   101
	m_CustomLevel = 0;
fyrenmoo@3129
   102
	m_CustomHandler = NULL;
fyrenmoo@3129
   103
}
fyrenmoo@3129
   104
fyrenmoo@3129
   105
CGameConfig::~CGameConfig()
fyrenmoo@3129
   106
{
fyrenmoo@3129
   107
//	delete m_pStrings;
fyrenmoo@3129
   108
}
fyrenmoo@3129
   109
fyrenmoo@3129
   110
SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *name)
fyrenmoo@3129
   111
{
fyrenmoo@3129
   112
	if (m_IgnoreLevel)
fyrenmoo@3129
   113
	{
fyrenmoo@3129
   114
		m_IgnoreLevel++;
fyrenmoo@3129
   115
		return SMCResult_Continue;
fyrenmoo@3129
   116
	}
fyrenmoo@3129
   117
fyrenmoo@3129
   118
	switch (m_ParseState)
fyrenmoo@3129
   119
	{
fyrenmoo@3129
   120
	case PSTATE_NONE:
fyrenmoo@3129
   121
		{
fyrenmoo@3129
   122
			if (strcmp(name, "Games") == 0)
fyrenmoo@3129
   123
			{
fyrenmoo@3129
   124
				m_ParseState = PSTATE_GAMES;
fyrenmoo@3129
   125
			} else {
fyrenmoo@3129
   126
				m_IgnoreLevel++;
fyrenmoo@3129
   127
			}
fyrenmoo@3129
   128
			break;
fyrenmoo@3129
   129
		}
fyrenmoo@3129
   130
	case PSTATE_GAMES:
fyrenmoo@3129
   131
		{
fyrenmoo@3129
   132
			if (strcmp(name, "*") == 0 ||
fyrenmoo@3129
   133
				strcmp(name, "#default") == 0 ||
fyrenmoo@3129
   134
				DoesGameMatch(name))
fyrenmoo@3129
   135
			{
fyrenmoo@3129
   136
				bShouldBeReadingDefault = true;
fyrenmoo@3129
   137
				m_ParseState = PSTATE_GAMEDEFS;
fyrenmoo@3129
   138
				strncopy(m_Game, name, sizeof(m_Game));
fyrenmoo@3129
   139
			} else {
fyrenmoo@3129
   140
				m_IgnoreLevel++;
fyrenmoo@3129
   141
			}
fyrenmoo@3129
   142
			break;
fyrenmoo@3129
   143
		}
fyrenmoo@3129
   144
	case PSTATE_GAMEDEFS:
fyrenmoo@3129
   145
		{
fyrenmoo@3129
   146
			if (strcmp(name, "Offsets") == 0)
fyrenmoo@3129
   147
			{
fyrenmoo@3129
   148
				m_ParseState = PSTATE_GAMEDEFS_OFFSETS;
fyrenmoo@3129
   149
			}
fyrenmoo@3129
   150
			else if (strcmp(name, "Keys") == 0)
fyrenmoo@3129
   151
			{
fyrenmoo@3129
   152
				m_ParseState = PSTATE_GAMEDEFS_KEYS;
fyrenmoo@3129
   153
			}
fyrenmoo@3129
   154
			else if ((strcmp(name, "#supported") == 0) && (strcmp(m_Game, "#default") == 0))
fyrenmoo@3129
   155
			{
fyrenmoo@3129
   156
				m_ParseState = PSTATE_GAMEDEFS_SUPPORTED;
fyrenmoo@3129
   157
				/* Ignore this section unless we get a game. */
fyrenmoo@3129
   158
				bShouldBeReadingDefault = false;
fyrenmoo@3129
   159
				had_game = false;
fyrenmoo@3129
   160
				matched_game = false;
fyrenmoo@3129
   161
				had_engine = false;
fyrenmoo@3129
   162
				matched_engine = false;
fyrenmoo@3129
   163
			}
fyrenmoo@3129
   164
			else if (strcmp(name, "Signatures") == 0)
fyrenmoo@3129
   165
			{
fyrenmoo@3129
   166
				m_ParseState = PSTATE_GAMEDEFS_SIGNATURES;
fyrenmoo@3129
   167
			}
fyrenmoo@3129
   168
			else if (strcmp(name, "CRC") == 0)
fyrenmoo@3129
   169
			{
fyrenmoo@3129
   170
#if 0
fyrenmoo@3129
   171
				m_ParseState = PSTATE_GAMEDEFS_CRC;
fyrenmoo@3129
   172
				bShouldBeReadingDefault = false;
fyrenmoo@3129
   173
#endif
fyrenmoo@3129
   174
			}
fyrenmoo@3129
   175
			else
fyrenmoo@3129
   176
			{
fyrenmoo@3129
   177
#if 0
fyrenmoo@3129
   178
				ITextListener_SMC **pListen = g_GameConfigs.m_customHandlers.retrieve(name);
fyrenmoo@3129
   179
fyrenmoo@3129
   180
				if (pListen != NULL)
fyrenmoo@3129
   181
				{
fyrenmoo@3129
   182
					m_CustomLevel = 0;
fyrenmoo@3129
   183
					m_ParseState = PSTATE_GAMEDEFS_CUSTOM;
fyrenmoo@3129
   184
					m_CustomHandler = *pListen;
fyrenmoo@3129
   185
					m_CustomHandler->ReadSMC_ParseStart();
fyrenmoo@3129
   186
					break;
fyrenmoo@3129
   187
				}
fyrenmoo@3129
   188
#endif
fyrenmoo@3129
   189
			}
fyrenmoo@3129
   190
			break;
fyrenmoo@3129
   191
		}
fyrenmoo@3129
   192
	case PSTATE_GAMEDEFS_OFFSETS:
fyrenmoo@3129
   193
		{
fyrenmoo@3129
   194
			m_Prop[0] = '\0';
fyrenmoo@3129
   195
			m_Class[0] = '\0';
fyrenmoo@3129
   196
			tempOffset = new Offset();
fyrenmoo@3129
   197
			tempOffset->setName(name);
fyrenmoo@3129
   198
			m_ParseState = PSTATE_GAMEDEFS_OFFSETS_OFFSET;
fyrenmoo@3129
   199
			break;
fyrenmoo@3129
   200
		}
fyrenmoo@3129
   201
	case PSTATE_GAMEDEFS_SIGNATURES:
fyrenmoo@3129
   202
		{
fyrenmoo@3129
   203
			tempSig = new Sig();
fyrenmoo@3129
   204
			tempSig->setName(name);
fyrenmoo@3129
   205
			m_ParseState = PSTATE_GAMEDEFS_SIGNATURES_SIG;
fyrenmoo@3129
   206
			break;
fyrenmoo@3129
   207
		}
fyrenmoo@3129
   208
#if 0
fyrenmoo@3129
   209
	case PSTATE_GAMEDEFS_CRC:
fyrenmoo@3129
   210
		{
fyrenmoo@3129
   211
			char error[255];
fyrenmoo@3129
   212
			error[0] = '\0';
fyrenmoo@3129
   213
			if (strcmp(name, "server") != 0)
fyrenmoo@3129
   214
			{
fyrenmoo@3129
   215
				UTIL_Format(error, sizeof(error), "Unrecognized library \"%s\"", name);
fyrenmoo@3129
   216
			} 
fyrenmoo@3129
   217
			else if (!s_ServerBinCRC_Ok)
fyrenmoo@3129
   218
			{
fyrenmoo@3129
   219
				FILE *fp;
fyrenmoo@3129
   220
				char path[PLATFORM_MAX_PATH];
fyrenmoo@3129
   221
fyrenmoo@3129
   222
				g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "bin/" PLATFORM_SERVER_BINARY);
fyrenmoo@3129
   223
				if ((fp = fopen(path, "rb")) == NULL)
fyrenmoo@3129
   224
				{
fyrenmoo@3129
   225
					UTIL_Format(error, sizeof(error), "Could not open binary: %s", path);
fyrenmoo@3129
   226
				} else {
fyrenmoo@3129
   227
					size_t size;
fyrenmoo@3129
   228
					void *buffer;
fyrenmoo@3129
   229
fyrenmoo@3129
   230
					fseek(fp, 0, SEEK_END);
fyrenmoo@3129
   231
					size = ftell(fp);
fyrenmoo@3129
   232
					fseek(fp, 0, SEEK_SET);
fyrenmoo@3129
   233
fyrenmoo@3129
   234
					buffer = malloc(size);
fyrenmoo@3129
   235
					fread(buffer, size, 1, fp);
fyrenmoo@3129
   236
					s_ServerBinCRC = UTIL_CRC32(buffer, size);
fyrenmoo@3129
   237
					free(buffer);
fyrenmoo@3129
   238
					s_ServerBinCRC_Ok = true;
fyrenmoo@3129
   239
					fclose(fp);
fyrenmoo@3129
   240
				}
fyrenmoo@3129
   241
			}
fyrenmoo@3129
   242
			if (error[0] != '\0')
fyrenmoo@3129
   243
			{
fyrenmoo@3129
   244
				m_IgnoreLevel = 1;
fyrenmoo@3129
   245
				g_Logger.LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile);
fyrenmoo@3129
   246
				g_Logger.LogError("[SM] %s", error);
fyrenmoo@3129
   247
			} else {
fyrenmoo@3129
   248
				m_ParseState = PSTATE_GAMEDEFS_CRC_BINARY;
fyrenmoo@3129
   249
			}
fyrenmoo@3129
   250
			break;
fyrenmoo@3129
   251
		}
fyrenmoo@3129
   252
	case PSTATE_GAMEDEFS_CUSTOM:
fyrenmoo@3129
   253
		{
fyrenmoo@3129
   254
			m_CustomLevel++;
fyrenmoo@3129
   255
			return m_CustomHandler->ReadSMC_NewSection(states, name);
fyrenmoo@3129
   256
			break;
fyrenmoo@3129
   257
		}
fyrenmoo@3129
   258
#endif
fyrenmoo@3129
   259
	/* No sub-sections allowed:
fyrenmoo@3129
   260
	 case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
fyrenmoo@3129
   261
	 case PSTATE_GAMEDEFS_KEYS:
fyrenmoo@3129
   262
	 case PSTATE_GAMEDEFS_SUPPORTED:
fyrenmoo@3129
   263
	 case PSTATE_GAMEDEFS_SIGNATURES_SIG:
fyrenmoo@3129
   264
	 case PSTATE_GAMEDEFS_CRC_BINARY:
fyrenmoo@3129
   265
	 */
fyrenmoo@3129
   266
	default:
fyrenmoo@3129
   267
		{
fyrenmoo@3129
   268
			/* If we don't know what we got, start ignoring */
fyrenmoo@3129
   269
			m_IgnoreLevel++;
fyrenmoo@3129
   270
			break;
fyrenmoo@3129
   271
		}
fyrenmoo@3129
   272
	}
fyrenmoo@3129
   273
fyrenmoo@3129
   274
	return SMCResult_Continue;
fyrenmoo@3129
   275
}
fyrenmoo@3129
   276
fyrenmoo@3129
   277
SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
fyrenmoo@3129
   278
{
fyrenmoo@3129
   279
	if (m_IgnoreLevel)
fyrenmoo@3129
   280
	{
fyrenmoo@3129
   281
		return SMCResult_Continue;
fyrenmoo@3129
   282
	}
fyrenmoo@3129
   283
fyrenmoo@3129
   284
	if (m_ParseState == PSTATE_GAMEDEFS_OFFSETS_OFFSET)
fyrenmoo@3129
   285
	{
fyrenmoo@3129
   286
		if (strcmp(key, "class") == 0)
fyrenmoo@3129
   287
		{
fyrenmoo@3129
   288
			strncopy(m_Class, value, sizeof(m_Class));
fyrenmoo@3129
   289
		} else if (strcmp(key, "prop") == 0) {
fyrenmoo@3129
   290
			strncopy(m_Prop, value, sizeof(m_Prop));
fyrenmoo@3129
   291
		} else /*if (strcmp(key, PLATFORM_NAME) == 0) */ {
fyrenmoo@3129
   292
			int val = atoi(value);
fyrenmoo@3129
   293
//			sm_trie_replace(m_pOffsets, m_offset, (void *)val);
fyrenmoo@3129
   294
			if (strcmp(key, "windows") == 0) tempOffset->setWin(val);
fyrenmoo@3129
   295
			else if (strcmp(key, "linux") == 0) tempOffset->setLin(val);
fyrenmoo@3129
   296
		}
fyrenmoo@3129
   297
	} else if (m_ParseState == PSTATE_GAMEDEFS_KEYS) {
fyrenmoo@3129
   298
		m_Keys[key] = value;
fyrenmoo@3129
   299
//		printf("Inserting %s - %s\n", key, value);
fyrenmoo@3129
   300
//		int id = m_pStrings->AddString(value);
fyrenmoo@3129
   301
//		sm_trie_replace(m_pKeys, key, (void *)id);
fyrenmoo@3129
   302
	} else if (m_ParseState == PSTATE_GAMEDEFS_SUPPORTED) {
fyrenmoo@3129
   303
		if (strcmp(key, "game") == 0)
fyrenmoo@3129
   304
		{
fyrenmoo@3129
   305
			had_game = true;
fyrenmoo@3129
   306
			if (DoesGameMatch(value))
fyrenmoo@3129
   307
			{
fyrenmoo@3129
   308
				matched_game = true;
fyrenmoo@3129
   309
			}
fyrenmoo@3129
   310
			if ((!had_engine && matched_game) || (matched_engine && matched_game))
fyrenmoo@3129
   311
			{
fyrenmoo@3129
   312
				bShouldBeReadingDefault = true;
fyrenmoo@3129
   313
			}
fyrenmoo@3129
   314
		}
fyrenmoo@3129
   315
		else if (strcmp(key, "engine") == 0)
fyrenmoo@3129
   316
		{
fyrenmoo@3129
   317
			had_engine = true;
fyrenmoo@3129
   318
			if (DoesEngineMatch(value))
fyrenmoo@3129
   319
			{
fyrenmoo@3129
   320
				matched_engine = true;
fyrenmoo@3129
   321
			}
fyrenmoo@3129
   322
			if ((!had_game && matched_engine) || (matched_game && matched_engine))
fyrenmoo@3129
   323
			{
fyrenmoo@3129
   324
				bShouldBeReadingDefault = true;
fyrenmoo@3129
   325
			}
fyrenmoo@3129
   326
		}
fyrenmoo@3129
   327
	} else if (m_ParseState == PSTATE_GAMEDEFS_SIGNATURES_SIG) {
fyrenmoo@3129
   328
		if (strcmp(key, "windows") == 0) tempSig->setWin(value);
fyrenmoo@3129
   329
		else if (strcmp(key, "linux") == 0) tempSig->setLin(value);
fyrenmoo@3129
   330
		else if (strcmp(key, "library") == 0) tempSig->setLib(value);
fyrenmoo@3129
   331
	} else if (m_ParseState == PSTATE_GAMEDEFS_CRC_BINARY) {
fyrenmoo@3129
   332
		if (strcmp(key, PLATFORM_NAME) == 0 
fyrenmoo@3129
   333
			&& s_ServerBinCRC_Ok
fyrenmoo@3129
   334
			&& !bShouldBeReadingDefault)
fyrenmoo@3129
   335
		{
fyrenmoo@3129
   336
			unsigned int crc = 0;
fyrenmoo@3129
   337
			sscanf(value, "%08X", &crc);
fyrenmoo@3129
   338
			if (s_ServerBinCRC == crc)
fyrenmoo@3129
   339
			{
fyrenmoo@3129
   340
				bShouldBeReadingDefault = true;
fyrenmoo@3129
   341
			}
fyrenmoo@3129
   342
		}
fyrenmoo@3129
   343
	} else if (m_ParseState == PSTATE_GAMEDEFS_CUSTOM) {
fyrenmoo@3129
   344
		return m_CustomHandler->ReadSMC_KeyValue(states, key, value);
fyrenmoo@3129
   345
	}
fyrenmoo@3129
   346
fyrenmoo@3129
   347
	return SMCResult_Continue;
fyrenmoo@3129
   348
}
fyrenmoo@3129
   349
fyrenmoo@3129
   350
SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
fyrenmoo@3129
   351
{
fyrenmoo@3129
   352
	if (m_IgnoreLevel)
fyrenmoo@3129
   353
	{
fyrenmoo@3129
   354
		m_IgnoreLevel--;
fyrenmoo@3129
   355
		return SMCResult_Continue;
fyrenmoo@3129
   356
	}
fyrenmoo@3129
   357
fyrenmoo@3129
   358
	if (m_CustomLevel)
fyrenmoo@3129
   359
	{
fyrenmoo@3129
   360
		m_CustomLevel--;
fyrenmoo@3129
   361
		m_CustomHandler->ReadSMC_LeavingSection(states);
fyrenmoo@3129
   362
		return SMCResult_Continue;
fyrenmoo@3129
   363
	}
fyrenmoo@3129
   364
fyrenmoo@3129
   365
	switch (m_ParseState)
fyrenmoo@3129
   366
	{
fyrenmoo@3129
   367
	case PSTATE_GAMES:
fyrenmoo@3129
   368
		{
fyrenmoo@3129
   369
			m_ParseState = PSTATE_NONE;
fyrenmoo@3129
   370
			break;
fyrenmoo@3129
   371
		}
fyrenmoo@3129
   372
	case PSTATE_GAMEDEFS:
fyrenmoo@3129
   373
		{
fyrenmoo@3129
   374
			m_ParseState = PSTATE_GAMES;
fyrenmoo@3129
   375
			break;
fyrenmoo@3129
   376
		}
fyrenmoo@3129
   377
	case PSTATE_GAMEDEFS_CUSTOM:
fyrenmoo@3129
   378
		{
fyrenmoo@3129
   379
			m_ParseState = PSTATE_GAMEDEFS;
fyrenmoo@3129
   380
			m_CustomHandler->ReadSMC_ParseEnd(false, false);
fyrenmoo@3129
   381
			break;
fyrenmoo@3129
   382
		}
fyrenmoo@3129
   383
	case PSTATE_GAMEDEFS_KEYS:
fyrenmoo@3129
   384
	case PSTATE_GAMEDEFS_OFFSETS:
fyrenmoo@3129
   385
		{
fyrenmoo@3129
   386
			m_ParseState = PSTATE_GAMEDEFS;
fyrenmoo@3129
   387
			break;
fyrenmoo@3129
   388
		}
fyrenmoo@3129
   389
	case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
fyrenmoo@3129
   390
		{
fyrenmoo@3129
   391
			m_Offsets.push_back(*tempOffset);
fyrenmoo@3129
   392
#if 0
fyrenmoo@3129
   393
			/* Parse the offset... */
fyrenmoo@3129
   394
			if (m_Class[0] != '\0'
fyrenmoo@3129
   395
				&& m_Prop[0] != '\0')
fyrenmoo@3129
   396
			{
fyrenmoo@3129
   397
				SendProp *pProp = g_HL2.FindInSendTable(m_Class, m_Prop);
fyrenmoo@3129
   398
				if (pProp)
fyrenmoo@3129
   399
				{
fyrenmoo@3129
   400
					int val = pProp->GetOffset();
fyrenmoo@3129
   401
					sm_trie_replace(m_pOffsets, m_offset, (void *)val);
fyrenmoo@3129
   402
					sm_trie_replace(m_pProps, m_offset, pProp);
fyrenmoo@3129
   403
				} else {
fyrenmoo@3129
   404
					/* Check if it's a non-default game and no offsets exist */
fyrenmoo@3129
   405
					if (((strcmp(m_Game, "*") != 0) && strcmp(m_Game, "#default") != 0)
fyrenmoo@3129
   406
						&& (!sm_trie_retrieve(m_pOffsets, m_offset, NULL)))
fyrenmoo@3129
   407
					{
fyrenmoo@3129
   408
						g_Logger.LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")", 
fyrenmoo@3129
   409
							m_Class,
fyrenmoo@3129
   410
							m_Prop,
fyrenmoo@3129
   411
							m_CurFile,
fyrenmoo@3129
   412
							m_Game);
fyrenmoo@3129
   413
					}
fyrenmoo@3129
   414
				}
fyrenmoo@3129
   415
			}
fyrenmoo@3129
   416
#endif
fyrenmoo@3129
   417
			m_ParseState = PSTATE_GAMEDEFS_OFFSETS;
fyrenmoo@3129
   418
			break;
fyrenmoo@3129
   419
		}
fyrenmoo@3129
   420
	case PSTATE_GAMEDEFS_CRC:
fyrenmoo@3129
   421
	case PSTATE_GAMEDEFS_SUPPORTED:
fyrenmoo@3129
   422
		{
fyrenmoo@3129
   423
			if (!bShouldBeReadingDefault)
fyrenmoo@3129
   424
			{
fyrenmoo@3129
   425
				/* If we shouldn't read the rest of this section, set the ignore level. */
fyrenmoo@3129
   426
				m_IgnoreLevel = 1;
fyrenmoo@3129
   427
				m_ParseState = PSTATE_GAMES;
fyrenmoo@3129
   428
			} else {
fyrenmoo@3129
   429
				m_ParseState = PSTATE_GAMEDEFS;
fyrenmoo@3129
   430
			}
fyrenmoo@3129
   431
			break;
fyrenmoo@3129
   432
		}
fyrenmoo@3129
   433
	case PSTATE_GAMEDEFS_CRC_BINARY:
fyrenmoo@3129
   434
		{
fyrenmoo@3129
   435
			m_ParseState = PSTATE_GAMEDEFS_CRC;
fyrenmoo@3129
   436
			break;
fyrenmoo@3129
   437
		}
fyrenmoo@3129
   438
	case PSTATE_GAMEDEFS_SIGNATURES:
fyrenmoo@3129
   439
		{
fyrenmoo@3129
   440
			m_ParseState = PSTATE_GAMEDEFS;
fyrenmoo@3129
   441
			break;
fyrenmoo@3129
   442
		}
fyrenmoo@3129
   443
	case PSTATE_GAMEDEFS_SIGNATURES_SIG:
fyrenmoo@3129
   444
		{
fyrenmoo@3129
   445
			m_Sigs.push_back(*tempSig);
fyrenmoo@3129
   446
#if 0
fyrenmoo@3129
   447
			if (s_TempSig.library[0] == '\0')
fyrenmoo@3129
   448
			{
fyrenmoo@3129
   449
				/* assume server */
fyrenmoo@3129
   450
				strncopy(s_TempSig.library, "server", sizeof(s_TempSig.library));
fyrenmoo@3129
   451
			}
fyrenmoo@3129
   452
			void *addrInBase = NULL;
fyrenmoo@3129
   453
			if (strcmp(s_TempSig.library, "server") == 0)
fyrenmoo@3129
   454
			{
fyrenmoo@3129
   455
				addrInBase = (void *)g_SMAPI->GetServerFactory(false);
fyrenmoo@3129
   456
			} else if (strcmp(s_TempSig.library, "engine") == 0) {
fyrenmoo@3129
   457
				addrInBase = (void *)g_SMAPI->GetEngineFactory(false);
fyrenmoo@3129
   458
			}
fyrenmoo@3129
   459
			void *final_addr = NULL;
fyrenmoo@3129
   460
			if (addrInBase == NULL)
fyrenmoo@3129
   461
			{
fyrenmoo@3129
   462
				g_Logger.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")", 
fyrenmoo@3129
   463
					s_TempSig.library, 
fyrenmoo@3129
   464
					m_CurFile);
fyrenmoo@3129
   465
			} else {
fyrenmoo@3129
   466
#if defined PLATFORM_LINUX
fyrenmoo@3129
   467
				if (s_TempSig.sig[0] == '@')
fyrenmoo@3129
   468
				{
fyrenmoo@3129
   469
					Dl_info info;
fyrenmoo@3129
   470
					/* GNU only: returns 0 on error, inconsistent! >:[ */
fyrenmoo@3129
   471
					if (dladdr(addrInBase, &info) != 0)
fyrenmoo@3129
   472
					{
fyrenmoo@3129
   473
						void *handle = dlopen(info.dli_fname, RTLD_NOW);
fyrenmoo@3129
   474
						if (handle)
fyrenmoo@3129
   475
						{
fyrenmoo@3129
   476
							final_addr = dlsym(handle, &s_TempSig.sig[1]);
fyrenmoo@3129
   477
							dlclose(handle);
fyrenmoo@3129
   478
						} else {
fyrenmoo@3129
   479
							g_Logger.LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")",
fyrenmoo@3129
   480
								s_TempSig.library,
fyrenmoo@3129
   481
								m_File);
fyrenmoo@3129
   482
						}
fyrenmoo@3129
   483
					} else {
fyrenmoo@3129
   484
						g_Logger.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")",
fyrenmoo@3129
   485
							s_TempSig.library,
fyrenmoo@3129
   486
							m_File);
fyrenmoo@3129
   487
					}
fyrenmoo@3129
   488
				}
fyrenmoo@3129
   489
				if (final_addr)
fyrenmoo@3129
   490
				{
fyrenmoo@3129
   491
					goto skip_find;
fyrenmoo@3129
   492
				}
fyrenmoo@3129
   493
#endif
fyrenmoo@3129
   494
				/* First, preprocess the signature */
fyrenmoo@3129
   495
				char real_sig[511];
fyrenmoo@3129
   496
				size_t real_bytes;
fyrenmoo@3129
   497
				size_t length;
fyrenmoo@3129
   498
fyrenmoo@3129
   499
				real_bytes = 0;
fyrenmoo@3129
   500
				length = strlen(s_TempSig.sig);
fyrenmoo@3129
   501
fyrenmoo@3129
   502
				for (size_t i=0; i<length; i++)
fyrenmoo@3129
   503
				{
fyrenmoo@3129
   504
					if (real_bytes >= sizeof(real_sig))
fyrenmoo@3129
   505
					{
fyrenmoo@3129
   506
						break;
fyrenmoo@3129
   507
					}
fyrenmoo@3129
   508
					real_sig[real_bytes++] = s_TempSig.sig[i];
fyrenmoo@3129
   509
					if (s_TempSig.sig[i] == '\\'
fyrenmoo@3129
   510
						&& s_TempSig.sig[i+1] == 'x')
fyrenmoo@3129
   511
					{
fyrenmoo@3129
   512
						if (i + 3 >= length)
fyrenmoo@3129
   513
						{
fyrenmoo@3129
   514
							continue;
fyrenmoo@3129
   515
						}
fyrenmoo@3129
   516
						/* Get the hex part */
fyrenmoo@3129
   517
						char s_byte[3];
fyrenmoo@3129
   518
						int r_byte;
fyrenmoo@3129
   519
						s_byte[0] = s_TempSig.sig[i+2];
fyrenmoo@3129
   520
						s_byte[1] = s_TempSig.sig[i+3];
fyrenmoo@3129
   521
						s_byte[2] = '\0';
fyrenmoo@3129
   522
						/* Read it as an integer */
fyrenmoo@3129
   523
						sscanf(s_byte, "%x", &r_byte);
fyrenmoo@3129
   524
						/* Save the value */
fyrenmoo@3129
   525
						real_sig[real_bytes-1] = r_byte;
fyrenmoo@3129
   526
						/* Adjust index */
fyrenmoo@3129
   527
						i += 3;
fyrenmoo@3129
   528
					}
fyrenmoo@3129
   529
				}
fyrenmoo@3129
   530
fyrenmoo@3129
   531
				if (real_bytes >= 1)
fyrenmoo@3129
   532
				{
fyrenmoo@3129
   533
					final_addr = g_MemUtils.FindPattern(addrInBase, real_sig, real_bytes);
fyrenmoo@3129
   534
				}
fyrenmoo@3129
   535
			}
fyrenmoo@3129
   536
fyrenmoo@3129
   537
#if defined PLATFORM_LINUX
fyrenmoo@3129
   538
skip_find:
fyrenmoo@3129
   539
#endif
fyrenmoo@3129
   540
			sm_trie_replace(m_pSigs, m_offset, final_addr);
fyrenmoo@3129
   541
#endif
fyrenmoo@3129
   542
			m_ParseState = PSTATE_GAMEDEFS_SIGNATURES;
fyrenmoo@3129
   543
fyrenmoo@3129
   544
			break;
fyrenmoo@3129
   545
		}
fyrenmoo@3129
   546
	}
fyrenmoo@3129
   547
fyrenmoo@3129
   548
	return SMCResult_Continue;
fyrenmoo@3129
   549
}
fyrenmoo@3129
   550
fyrenmoo@3129
   551
#define MSTATE_NONE		0
fyrenmoo@3129
   552
#define MSTATE_MAIN		1
fyrenmoo@3129
   553
#define MSTATE_FILE		2
fyrenmoo@3129
   554
fyrenmoo@3129
   555
class MasterReader : public ITextListener_SMC
fyrenmoo@3129
   556
{
fyrenmoo@3129
   557
public:
fyrenmoo@3129
   558
	virtual void ReadSMC_ParseStart()
fyrenmoo@3129
   559
	{
fyrenmoo@3129
   560
		state = MSTATE_NONE;
fyrenmoo@3129
   561
		ignoreLevel = 0;
fyrenmoo@3129
   562
	}
fyrenmoo@3129
   563
fyrenmoo@3129
   564
	virtual SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
fyrenmoo@3129
   565
	{
fyrenmoo@3129
   566
		if (ignoreLevel)
fyrenmoo@3129
   567
		{
fyrenmoo@3129
   568
			return SMCResult_Continue;
fyrenmoo@3129
   569
		}
fyrenmoo@3129
   570
fyrenmoo@3129
   571
		if (state == MSTATE_NONE)
fyrenmoo@3129
   572
		{
fyrenmoo@3129
   573
			if (strcmp(name, "Game Master") == 0)
fyrenmoo@3129
   574
			{
fyrenmoo@3129
   575
				state = MSTATE_MAIN;
fyrenmoo@3129
   576
			}
fyrenmoo@3129
   577
			else
fyrenmoo@3129
   578
			{
fyrenmoo@3129
   579
				ignoreLevel++;
fyrenmoo@3129
   580
			}
fyrenmoo@3129
   581
		}
fyrenmoo@3129
   582
		else if (state == MSTATE_MAIN)
fyrenmoo@3129
   583
		{
fyrenmoo@3129
   584
			strncopy(cur_file, name, sizeof(cur_file));
fyrenmoo@3129
   585
			had_engine = false;
fyrenmoo@3129
   586
			matched_engine = false;
fyrenmoo@3129
   587
			had_game = false;
fyrenmoo@3129
   588
			matched_game = false;
fyrenmoo@3129
   589
			state = MSTATE_FILE;
fyrenmoo@3129
   590
		}
fyrenmoo@3129
   591
		else if (state == MSTATE_FILE)
fyrenmoo@3129
   592
		{
fyrenmoo@3129
   593
			ignoreLevel++;
fyrenmoo@3129
   594
		}
fyrenmoo@3129
   595
fyrenmoo@3129
   596
		return SMCResult_Continue;
fyrenmoo@3129
   597
	}
fyrenmoo@3129
   598
fyrenmoo@3129
   599
	virtual SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
fyrenmoo@3129
   600
	{
fyrenmoo@3129
   601
		if (ignoreLevel || state != MSTATE_FILE)
fyrenmoo@3129
   602
		{
fyrenmoo@3129
   603
			return SMCResult_Continue;
fyrenmoo@3129
   604
		}
fyrenmoo@3129
   605
fyrenmoo@3129
   606
		if (strcmp(key, "engine") == 0)
fyrenmoo@3129
   607
		{
fyrenmoo@3129
   608
			had_engine = true;
fyrenmoo@3129
   609
			if (DoesEngineMatch(value))
fyrenmoo@3129
   610
			{
fyrenmoo@3129
   611
				matched_engine = true;
fyrenmoo@3129
   612
			}
fyrenmoo@3129
   613
		}
fyrenmoo@3129
   614
		else if (strcmp(key, "game") == 0)
fyrenmoo@3129
   615
		{
fyrenmoo@3129
   616
			had_game = true;
fyrenmoo@3129
   617
			if (DoesGameMatch(value))
fyrenmoo@3129
   618
			{
fyrenmoo@3129
   619
				matched_game = true;
fyrenmoo@3129
   620
			}
fyrenmoo@3129
   621
		}
fyrenmoo@3129
   622
fyrenmoo@3129
   623
		return SMCResult_Continue;
fyrenmoo@3129
   624
	}
fyrenmoo@3129
   625
fyrenmoo@3129
   626
	virtual SMCResult ReadSMC_LeavingSection(const SMCStates *states)
fyrenmoo@3129
   627
	{
fyrenmoo@3129
   628
		if (ignoreLevel)
fyrenmoo@3129
   629
		{
fyrenmoo@3129
   630
			ignoreLevel--;
fyrenmoo@3129
   631
			return SMCResult_Continue;
fyrenmoo@3129
   632
		}
fyrenmoo@3129
   633
fyrenmoo@3129
   634
		if (state == MSTATE_FILE)
fyrenmoo@3129
   635
		{
fyrenmoo@3129
   636
			/* The four success conditions:
fyrenmoo@3129
   637
			 * 1. Needed nothing.
fyrenmoo@3129
   638
			 * 2. Needed game only.
fyrenmoo@3129
   639
			 * 3. Needed engine only.
fyrenmoo@3129
   640
			 * 4. Needed both engine and game.
fyrenmoo@3129
   641
			 * Final result is minimized via k-map.
fyrenmoo@3129
   642
			 */
fyrenmoo@3129
   643
#if 0
fyrenmoo@3129
   644
			if ((!had_engine && !had_game) ||
fyrenmoo@3129
   645
				(!had_engine && (had_game && matched_game)) ||
fyrenmoo@3129
   646
				(!had_game && (had_engine && matched_engine)) ||
fyrenmoo@3129
   647
				((had_game && had_engine) && (matched_game && matched_engine)))
fyrenmoo@3129
   648
#endif
fyrenmoo@3129
   649
			if ((!had_engine && !had_game) ||
fyrenmoo@3129
   650
				(!had_engine && matched_game) ||
fyrenmoo@3129
   651
				(!had_game && matched_engine) ||
fyrenmoo@3129
   652
				(matched_engine && matched_game))
fyrenmoo@3129
   653
			{
fyrenmoo@3129
   654
				fileList->push_back(cur_file);
fyrenmoo@3129
   655
			}
fyrenmoo@3129
   656
			state = MSTATE_MAIN;
fyrenmoo@3129
   657
		}
fyrenmoo@3129
   658
		else if (state == MSTATE_MAIN)
fyrenmoo@3129
   659
		{
fyrenmoo@3129
   660
			state = MSTATE_NONE;
fyrenmoo@3129
   661
		}
fyrenmoo@3129
   662
fyrenmoo@3129
   663
		return SMCResult_Continue;
fyrenmoo@3129
   664
	}
fyrenmoo@3129
   665
public:
fyrenmoo@3129
   666
	list<char*> *fileList;
fyrenmoo@3129
   667
	unsigned int state;
fyrenmoo@3129
   668
	unsigned int ignoreLevel;
fyrenmoo@3129
   669
	char cur_file[PLATFORM_MAX_PATH];
fyrenmoo@3129
   670
	bool had_engine;
fyrenmoo@3129
   671
	bool matched_engine;
fyrenmoo@3129
   672
	bool had_game;
fyrenmoo@3129
   673
	bool matched_game;
fyrenmoo@3129
   674
};
fyrenmoo@3129
   675
fyrenmoo@3129
   676
static MasterReader master_reader;
fyrenmoo@3129
   677
fyrenmoo@3129
   678
bool CGameConfig::Reparse(char *error, size_t maxlength)
fyrenmoo@3129
   679
{
fyrenmoo@3129
   680
	/* Reset cached data */
fyrenmoo@3129
   681
//	m_pStrings->Reset();
fyrenmoo@3129
   682
	m_Offsets.clear();
fyrenmoo@3129
   683
	m_Sigs.clear();
fyrenmoo@3129
   684
	
fyrenmoo@3129
   685
fyrenmoo@3129
   686
	char path[PLATFORM_MAX_PATH];
fyrenmoo@3129
   687
fyrenmoo@3129
   688
	/* See if we can use the extended gamedata format. */
fyrenmoo@3129
   689
	//TODO pass in path to gamedata somehow
fyrenmoo@3129
   690
//	g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "gamedata/%s/master.games.txt", m_File);
fyrenmoo@3129
   691
fyrenmoo@3129
   692
	/* Otherwise, it's time to parse the master. */
fyrenmoo@3129
   693
	SMCError err;
fyrenmoo@3129
   694
	SMCStates state = {0, 0};
fyrenmoo@3129
   695
	list<char*> fileList;
fyrenmoo@3129
   696
	master_reader.fileList = &fileList;
fyrenmoo@3129
   697
fyrenmoo@3129
   698
	err = textparsers->ParseSMCFile(path, &master_reader, &state, error, maxlength);
fyrenmoo@3129
   699
	if (err != SMCError_Okay)
fyrenmoo@3129
   700
	{
fyrenmoo@3129
   701
		const char *msg = textparsers->GetSMCErrorString(err);
fyrenmoo@3129
   702
fyrenmoo@3129
   703
		printf("[SM] Error parsing master gameconf file \"%s\":", path);
fyrenmoo@3129
   704
		printf("[SM] Error %d on line %d, col %d: %s", 
fyrenmoo@3129
   705
			err,
fyrenmoo@3129
   706
			state.line,
fyrenmoo@3129
   707
			state.col,
fyrenmoo@3129
   708
			msg ? msg : "Unknown error");
fyrenmoo@3129
   709
		exit(PARSE_ERROR);
fyrenmoo@3129
   710
	}
fyrenmoo@3129
   711
fyrenmoo@3129
   712
	/* Go through each file we found and parse it. */
fyrenmoo@3129
   713
	list<char*>::iterator iter;
fyrenmoo@3129
   714
	for (iter = fileList.begin(); iter != fileList.end(); iter++)
fyrenmoo@3129
   715
	{
fyrenmoo@3129
   716
		UTIL_Format(path, sizeof(path), "%s/%s", m_File, *iter);
fyrenmoo@3129
   717
		if (!EnterFile(path, error, maxlength))
fyrenmoo@3129
   718
		{
fyrenmoo@3129
   719
			return false;
fyrenmoo@3129
   720
		}
fyrenmoo@3129
   721
	}
fyrenmoo@3129
   722
fyrenmoo@3129
   723
	return true;
fyrenmoo@3129
   724
}
fyrenmoo@3129
   725
fyrenmoo@3129
   726
bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength)
fyrenmoo@3129
   727
{
fyrenmoo@3129
   728
	SMCError err;
fyrenmoo@3129
   729
	SMCStates state = {0, 0};
fyrenmoo@3129
   730
fyrenmoo@3129
   731
	/* Initialize parse states */
fyrenmoo@3129
   732
	m_IgnoreLevel = 0;
fyrenmoo@3129
   733
	bShouldBeReadingDefault = true;
fyrenmoo@3129
   734
	m_ParseState = PSTATE_NONE;
fyrenmoo@3129
   735
fyrenmoo@3129
   736
	if ((err=textparsers->ParseSMCFile(file, this, &state, error, maxlength))
fyrenmoo@3129
   737
		!= SMCError_Okay)
fyrenmoo@3129
   738
	{
fyrenmoo@3129
   739
		const char *msg;
fyrenmoo@3129
   740
fyrenmoo@3129
   741
		msg = textparsers->GetSMCErrorString(err);
fyrenmoo@3129
   742
fyrenmoo@3129
   743
		printf("[SM] Error parsing gameconfig file \"%s\":\n", file);
fyrenmoo@3129
   744
		printf("[SM] Error %d on line %d, col %d: %s\n", 
fyrenmoo@3129
   745
			err,
fyrenmoo@3129
   746
			state.line,
fyrenmoo@3129
   747
			state.col,
fyrenmoo@3129
   748
			msg ? msg : "Unknown error");
fyrenmoo@3129
   749
fyrenmoo@3129
   750
		if (m_ParseState == PSTATE_GAMEDEFS_CUSTOM)
fyrenmoo@3129
   751
		{
fyrenmoo@3129
   752
			//error occurred while parsing a custom section
fyrenmoo@3129
   753
			m_CustomHandler->ReadSMC_ParseEnd(true, true);
fyrenmoo@3129
   754
			m_CustomHandler = NULL;
fyrenmoo@3129
   755
			m_CustomLevel = 0;
fyrenmoo@3129
   756
		}
fyrenmoo@3129
   757
fyrenmoo@3129
   758
		exit(PARSE_ERROR);
fyrenmoo@3129
   759
	}
fyrenmoo@3129
   760
fyrenmoo@3129
   761
	return true;
fyrenmoo@3129
   762
}
fyrenmoo@3129
   763
fyrenmoo@3129
   764
#if 0
fyrenmoo@3129
   765
bool CGameConfig::GetOffset(const char *key, int *value)
fyrenmoo@3129
   766
{
fyrenmoo@3129
   767
	void *obj;
fyrenmoo@3129
   768
fyrenmoo@3129
   769
	if (!sm_trie_retrieve(m_pOffsets, key, &obj))
fyrenmoo@3129
   770
	{
fyrenmoo@3129
   771
		return false;
fyrenmoo@3129
   772
	}
fyrenmoo@3129
   773
fyrenmoo@3129
   774
	*value = (int)obj;
fyrenmoo@3129
   775
	
fyrenmoo@3129
   776
	return true;
fyrenmoo@3129
   777
}
fyrenmoo@3129
   778
fyrenmoo@3129
   779
const char *CGameConfig::GetKeyValue(const char *key)
fyrenmoo@3129
   780
{
fyrenmoo@3129
   781
	void *obj;
fyrenmoo@3129
   782
	if (!sm_trie_retrieve(m_pKeys, key, &obj))
fyrenmoo@3129
   783
	{
fyrenmoo@3129
   784
		return NULL;
fyrenmoo@3129
   785
	}
fyrenmoo@3129
   786
	return m_pStrings->GetString((int)obj);
fyrenmoo@3129
   787
}
fyrenmoo@3129
   788
fyrenmoo@3129
   789
SendProp *CGameConfig::GetSendProp(const char *key)
fyrenmoo@3129
   790
{
fyrenmoo@3129
   791
	SendProp *pProp;
fyrenmoo@3129
   792
fyrenmoo@3129
   793
	if (!sm_trie_retrieve(m_pProps, key, (void **)&pProp))
fyrenmoo@3129
   794
	{
fyrenmoo@3129
   795
		return NULL;
fyrenmoo@3129
   796
	}
fyrenmoo@3129
   797
fyrenmoo@3129
   798
	return pProp;
fyrenmoo@3129
   799
}
fyrenmoo@3129
   800
fyrenmoo@3129
   801
bool CGameConfig::GetMemSig(const char *key, void **addr)
fyrenmoo@3129
   802
{
fyrenmoo@3129
   803
	return sm_trie_retrieve(m_pSigs, key, addr);
fyrenmoo@3129
   804
}
fyrenmoo@3129
   805
fyrenmoo@3129
   806
void CGameConfig::IncRefCount()
fyrenmoo@3129
   807
{
fyrenmoo@3129
   808
	m_RefCount++;
fyrenmoo@3129
   809
}
fyrenmoo@3129
   810
fyrenmoo@3129
   811
unsigned int CGameConfig::DecRefCount()
fyrenmoo@3129
   812
{
fyrenmoo@3129
   813
	m_RefCount--;
fyrenmoo@3129
   814
	return m_RefCount;
fyrenmoo@3129
   815
}
fyrenmoo@3129
   816
#endif
fyrenmoo@3129
   817
fyrenmoo@3129
   818
const char *CGameConfig::GetKeyValue(const char *key)
fyrenmoo@3129
   819
{
fyrenmoo@3129
   820
	map<const char*,const char*,cmp_str>::iterator it = m_Keys.find(key);
fyrenmoo@3129
   821
	if (it == m_Keys.end()) return NULL;
fyrenmoo@3129
   822
fyrenmoo@3129
   823
	return it->second;
fyrenmoo@3129
   824
}
fyrenmoo@3129
   825
fyrenmoo@3129
   826
list<Offset> CGameConfig::GetOffsets() { return m_Offsets; }
fyrenmoo@3129
   827
list<Sig> CGameConfig::GetSigs() { return m_Sigs; }
fyrenmoo@3129
   828