1.1 --- a/core/GameConfigs.cpp Fri Jul 11 06:51:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,694 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include <string.h>
1.36 -#include <stdlib.h>
1.37 -#include "GameConfigs.h"
1.38 -#include "sm_stringutil.h"
1.39 -#include "sourcemod.h"
1.40 -#include "sourcemm_api.h"
1.41 -#include "HalfLife2.h"
1.42 -#include "Logger.h"
1.43 -#include "ShareSys.h"
1.44 -#include "MemoryUtils.h"
1.45 -#include "LibrarySys.h"
1.46 -#include "HandleSys.h"
1.47 -#include "sm_crc32.h"
1.48 -#include "GameDataFetcher.h"
1.49 -
1.50 -#if defined PLATFORM_LINUX
1.51 -#include <dlfcn.h>
1.52 -#endif
1.53 -
1.54 -GameConfigManager g_GameConfigs;
1.55 -IGameConfig *g_pGameConf = NULL;
1.56 -char g_Game[256];
1.57 -char g_GameDesc[256] = {'!', '\0'};
1.58 -char g_GameName[256] = {'$', '\0'};
1.59 -
1.60 -#define PSTATE_NONE 0
1.61 -#define PSTATE_GAMES 1
1.62 -#define PSTATE_GAMEDEFS 2
1.63 -#define PSTATE_GAMEDEFS_OFFSETS 3
1.64 -#define PSTATE_GAMEDEFS_OFFSETS_OFFSET 4
1.65 -#define PSTATE_GAMEDEFS_KEYS 5
1.66 -#define PSTATE_GAMEDEFS_SUPPORTED 6
1.67 -#define PSTATE_GAMEDEFS_SIGNATURES 7
1.68 -#define PSTATE_GAMEDEFS_SIGNATURES_SIG 8
1.69 -#define PSTATE_GAMEDEFS_CRC 9
1.70 -#define PSTATE_GAMEDEFS_CRC_BINARY 10
1.71 -
1.72 -#if defined PLATFORM_WINDOWS
1.73 -#define PLATFORM_NAME "windows"
1.74 -#define PLATFORM_SERVER_BINARY "server.dll"
1.75 -#elif defined PLATFORM_LINUX
1.76 -#define PLATFORM_NAME "linux"
1.77 -#define PLATFORM_SERVER_BINARY "server_i486.so"
1.78 -#endif
1.79 -
1.80 -struct TempSigInfo
1.81 -{
1.82 - void Reset()
1.83 - {
1.84 - library[0] = '\0';
1.85 - sig[0] = '\0';
1.86 - }
1.87 - char sig[512];
1.88 - char library[64];
1.89 -} s_TempSig;
1.90 -unsigned int s_ServerBinCRC;
1.91 -bool s_ServerBinCRC_Ok = false;
1.92 -
1.93 -CGameConfig::CGameConfig(const char *file)
1.94 -{
1.95 - m_pFile = sm_strdup(file);
1.96 - m_pOffsets = sm_trie_create();
1.97 - m_pProps = sm_trie_create();
1.98 - m_pKeys = sm_trie_create();
1.99 - m_pSigs = sm_trie_create();
1.100 - m_pStrings = new BaseStringTable(512);
1.101 - m_RefCount = 0;
1.102 -}
1.103 -
1.104 -CGameConfig::~CGameConfig()
1.105 -{
1.106 - sm_trie_destroy(m_pOffsets);
1.107 - sm_trie_destroy(m_pProps);
1.108 - sm_trie_destroy(m_pKeys);
1.109 - sm_trie_destroy(m_pSigs);
1.110 - delete [] m_pFile;
1.111 - delete m_pStrings;
1.112 -}
1.113 -
1.114 -SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *name)
1.115 -{
1.116 - if (m_IgnoreLevel)
1.117 - {
1.118 - m_IgnoreLevel++;
1.119 - return SMCResult_Continue;
1.120 - }
1.121 -
1.122 - switch (m_ParseState)
1.123 - {
1.124 - case PSTATE_NONE:
1.125 - {
1.126 - if (strcmp(name, "Games") == 0)
1.127 - {
1.128 - m_ParseState = PSTATE_GAMES;
1.129 - } else {
1.130 - m_IgnoreLevel++;
1.131 - }
1.132 - break;
1.133 - }
1.134 - case PSTATE_GAMES:
1.135 - {
1.136 - if ((strcmp(name, "*") == 0)
1.137 - || (strcmp(name, "#default") == 0)
1.138 - || (strcasecmp(name, g_Game) == 0)
1.139 - || (strcasecmp(name, g_GameDesc) == 0)
1.140 - || (strcasecmp(name, g_GameName) == 0))
1.141 - {
1.142 - bShouldBeReadingDefault = true;
1.143 - m_ParseState = PSTATE_GAMEDEFS;
1.144 - strncopy(m_Game, name, sizeof(m_Game));
1.145 - } else {
1.146 - m_IgnoreLevel++;
1.147 - }
1.148 - break;
1.149 - }
1.150 - case PSTATE_GAMEDEFS:
1.151 - {
1.152 - if (strcmp(name, "Offsets") == 0)
1.153 - {
1.154 - m_ParseState = PSTATE_GAMEDEFS_OFFSETS;
1.155 - }
1.156 - else if (strcmp(name, "Keys") == 0)
1.157 - {
1.158 - m_ParseState = PSTATE_GAMEDEFS_KEYS;
1.159 - }
1.160 - else if ((strcmp(name, "#supported") == 0)
1.161 - && (strcmp(m_Game, "#default") == 0))
1.162 - {
1.163 - m_ParseState = PSTATE_GAMEDEFS_SUPPORTED;
1.164 - /* Ignore this section unless we get a game. */
1.165 - bShouldBeReadingDefault = false;
1.166 - }
1.167 - else if (strcmp(name, "Signatures") == 0)
1.168 - {
1.169 - m_ParseState = PSTATE_GAMEDEFS_SIGNATURES;
1.170 - }
1.171 - else if (strcmp(name, "CRC") == 0)
1.172 - {
1.173 - m_ParseState = PSTATE_GAMEDEFS_CRC;
1.174 - bShouldBeReadingDefault = false;
1.175 - }
1.176 - else
1.177 - {
1.178 - m_IgnoreLevel++;
1.179 - }
1.180 - break;
1.181 - }
1.182 - case PSTATE_GAMEDEFS_OFFSETS:
1.183 - {
1.184 - m_Prop[0] = '\0';
1.185 - m_Class[0] = '\0';
1.186 - strncopy(m_offset, name, sizeof(m_offset));
1.187 - m_ParseState = PSTATE_GAMEDEFS_OFFSETS_OFFSET;
1.188 - break;
1.189 - }
1.190 - case PSTATE_GAMEDEFS_SIGNATURES:
1.191 - {
1.192 - strncopy(m_offset, name, sizeof(m_offset));
1.193 - s_TempSig.Reset();
1.194 - m_ParseState = PSTATE_GAMEDEFS_SIGNATURES_SIG;
1.195 - break;
1.196 - }
1.197 - case PSTATE_GAMEDEFS_CRC:
1.198 - {
1.199 - char error[255];
1.200 - error[0] = '\0';
1.201 - if (strcmp(name, "server") != 0)
1.202 - {
1.203 - UTIL_Format(error, sizeof(error), "Unrecognized library \"%s\"", name);
1.204 - }
1.205 - else if (!s_ServerBinCRC_Ok)
1.206 - {
1.207 - FILE *fp;
1.208 - char path[PLATFORM_MAX_PATH];
1.209 -
1.210 - g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "bin/" PLATFORM_SERVER_BINARY);
1.211 - if ((fp = fopen(path, "rb")) == NULL)
1.212 - {
1.213 - UTIL_Format(error, sizeof(error), "Could not open binary: %s", path);
1.214 - } else {
1.215 - size_t size;
1.216 - void *buffer;
1.217 -
1.218 - fseek(fp, 0, SEEK_END);
1.219 - size = ftell(fp);
1.220 - fseek(fp, 0, SEEK_SET);
1.221 -
1.222 - buffer = malloc(size);
1.223 - fread(buffer, size, 1, fp);
1.224 - s_ServerBinCRC = UTIL_CRC32(buffer, size);
1.225 - free(buffer);
1.226 - s_ServerBinCRC_Ok = true;
1.227 - }
1.228 - }
1.229 - if (error[0] != '\0')
1.230 - {
1.231 - m_IgnoreLevel = 1;
1.232 - g_Logger.LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_pFile);
1.233 - g_Logger.LogError("[SM] %s", error);
1.234 - } else {
1.235 - m_ParseState = PSTATE_GAMEDEFS_CRC_BINARY;
1.236 - }
1.237 - break;
1.238 - }
1.239 - /* No sub-sections allowed:
1.240 - case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
1.241 - case PSTATE_GAMEDEFS_KEYS:
1.242 - case PSTATE_GAMEDEFS_SUPPORTED:
1.243 - case PSTATE_GAMEDEFS_SIGNATURES_SIG:
1.244 - case PSTATE_GAMEDEFS_CRC_BINARY:
1.245 - */
1.246 - default:
1.247 - {
1.248 - /* If we don't know what we got, start ignoring */
1.249 - m_IgnoreLevel++;
1.250 - break;
1.251 - }
1.252 - }
1.253 -
1.254 - return SMCResult_Continue;
1.255 -}
1.256 -
1.257 -SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
1.258 -{
1.259 - if (m_IgnoreLevel)
1.260 - {
1.261 - return SMCResult_Continue;
1.262 - }
1.263 -
1.264 - if (m_ParseState == PSTATE_GAMEDEFS_OFFSETS_OFFSET)
1.265 - {
1.266 - if (strcmp(key, "class") == 0)
1.267 - {
1.268 - strncopy(m_Class, value, sizeof(m_Class));
1.269 - } else if (strcmp(key, "prop") == 0) {
1.270 - strncopy(m_Prop, value, sizeof(m_Prop));
1.271 - } else if (strcmp(key, PLATFORM_NAME) == 0) {
1.272 - int val = atoi(value);
1.273 - sm_trie_replace(m_pOffsets, m_offset, (void *)val);
1.274 - }
1.275 - } else if (m_ParseState == PSTATE_GAMEDEFS_KEYS) {
1.276 - int id = m_pStrings->AddString(value);
1.277 - sm_trie_replace(m_pKeys, key, (void *)id);
1.278 - } else if (m_ParseState == PSTATE_GAMEDEFS_SUPPORTED) {
1.279 - if (strcmp(key, "game") == 0
1.280 - && (strcasecmp(value, g_Game) == 0
1.281 - || strcasecmp(value, g_GameDesc) == 0
1.282 - || strcasecmp(value, g_GameName) == 0)
1.283 - )
1.284 - {
1.285 - bShouldBeReadingDefault = true;
1.286 - }
1.287 - } else if (m_ParseState == PSTATE_GAMEDEFS_SIGNATURES_SIG) {
1.288 - if (strcmp(key, PLATFORM_NAME) == 0)
1.289 - {
1.290 - strncopy(s_TempSig.sig, value, sizeof(s_TempSig.sig));
1.291 - } else if (strcmp(key, "library") == 0) {
1.292 - strncopy(s_TempSig.library, value, sizeof(s_TempSig.library));
1.293 - }
1.294 - } else if (m_ParseState == PSTATE_GAMEDEFS_CRC_BINARY) {
1.295 - if (strcmp(key, PLATFORM_NAME) == 0
1.296 - && s_ServerBinCRC_Ok
1.297 - && !bShouldBeReadingDefault)
1.298 - {
1.299 - unsigned int crc = 0;
1.300 - sscanf(value, "%08X", &crc);
1.301 - if (s_ServerBinCRC == crc)
1.302 - {
1.303 - bShouldBeReadingDefault = true;
1.304 - }
1.305 - }
1.306 - }
1.307 -
1.308 - return SMCResult_Continue;
1.309 -}
1.310 -
1.311 -SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
1.312 -{
1.313 - if (m_IgnoreLevel)
1.314 - {
1.315 - m_IgnoreLevel--;
1.316 - return SMCResult_Continue;
1.317 - }
1.318 -
1.319 - switch (m_ParseState)
1.320 - {
1.321 - case PSTATE_GAMES:
1.322 - {
1.323 - m_ParseState = PSTATE_NONE;
1.324 - break;
1.325 - }
1.326 - case PSTATE_GAMEDEFS:
1.327 - {
1.328 - m_ParseState = PSTATE_GAMES;
1.329 - break;
1.330 - }
1.331 - case PSTATE_GAMEDEFS_KEYS:
1.332 - case PSTATE_GAMEDEFS_OFFSETS:
1.333 - {
1.334 - m_ParseState = PSTATE_GAMEDEFS;
1.335 - break;
1.336 - }
1.337 - case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
1.338 - {
1.339 - /* Parse the offset... */
1.340 - if (m_Class[0] != '\0'
1.341 - && m_Prop[0] != '\0')
1.342 - {
1.343 - SendProp *pProp = g_HL2.FindInSendTable(m_Class, m_Prop);
1.344 - if (pProp)
1.345 - {
1.346 - int val = pProp->GetOffset();
1.347 - sm_trie_replace(m_pOffsets, m_offset, (void *)val);
1.348 - sm_trie_replace(m_pProps, m_offset, pProp);
1.349 - } else {
1.350 - /* Check if it's a non-default game and no offsets exist */
1.351 - if (((strcmp(m_Game, "*") != 0) && strcmp(m_Game, "#default") != 0)
1.352 - && (!sm_trie_retrieve(m_pOffsets, m_offset, NULL)))
1.353 - {
1.354 - g_Logger.LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")",
1.355 - m_Class,
1.356 - m_Prop,
1.357 - m_pFile,
1.358 - m_Game);
1.359 - }
1.360 - }
1.361 - }
1.362 - m_ParseState = PSTATE_GAMEDEFS_OFFSETS;
1.363 - break;
1.364 - }
1.365 - case PSTATE_GAMEDEFS_CRC:
1.366 - case PSTATE_GAMEDEFS_SUPPORTED:
1.367 - {
1.368 - if (!bShouldBeReadingDefault)
1.369 - {
1.370 - /* If we shouldn't read the rest of this section, set the ignore level. */
1.371 - m_IgnoreLevel = 1;
1.372 - m_ParseState = PSTATE_GAMES;
1.373 - } else {
1.374 - m_ParseState = PSTATE_GAMEDEFS;
1.375 - }
1.376 - break;
1.377 - }
1.378 - case PSTATE_GAMEDEFS_CRC_BINARY:
1.379 - {
1.380 - m_ParseState = PSTATE_GAMEDEFS_CRC;
1.381 - break;
1.382 - }
1.383 - case PSTATE_GAMEDEFS_SIGNATURES:
1.384 - {
1.385 - m_ParseState = PSTATE_GAMEDEFS;
1.386 - break;
1.387 - }
1.388 - case PSTATE_GAMEDEFS_SIGNATURES_SIG:
1.389 - {
1.390 - if (s_TempSig.library[0] == '\0')
1.391 - {
1.392 - /* assume server */
1.393 - strncopy(s_TempSig.library, "server", sizeof(s_TempSig.library));
1.394 - }
1.395 - void *addrInBase = NULL;
1.396 - if (strcmp(s_TempSig.library, "server") == 0)
1.397 - {
1.398 - addrInBase = (void *)g_SMAPI->GetServerFactory(false);
1.399 - } else if (strcmp(s_TempSig.library, "engine") == 0) {
1.400 - addrInBase = (void *)g_SMAPI->GetEngineFactory(false);
1.401 - }
1.402 - void *final_addr = NULL;
1.403 - if (addrInBase == NULL)
1.404 - {
1.405 - g_Logger.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")",
1.406 - s_TempSig.library,
1.407 - m_pFile);
1.408 - } else {
1.409 -#if defined PLATFORM_LINUX
1.410 - if (s_TempSig.sig[0] == '@')
1.411 - {
1.412 - Dl_info info;
1.413 - /* GNU only: returns 0 on error, inconsistent! >:[ */
1.414 - if (dladdr(addrInBase, &info) != 0)
1.415 - {
1.416 - void *handle = dlopen(info.dli_fname, RTLD_NOW);
1.417 - if (handle)
1.418 - {
1.419 - final_addr = dlsym(handle, &s_TempSig.sig[1]);
1.420 - dlclose(handle);
1.421 - } else {
1.422 - g_Logger.LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")",
1.423 - s_TempSig.library,
1.424 - m_pFile);
1.425 - }
1.426 - } else {
1.427 - g_Logger.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")",
1.428 - s_TempSig.library,
1.429 - m_pFile);
1.430 - }
1.431 - }
1.432 - if (final_addr)
1.433 - {
1.434 - goto skip_find;
1.435 - }
1.436 -#endif
1.437 - /* First, preprocess the signature */
1.438 - char real_sig[511];
1.439 - size_t real_bytes;
1.440 - size_t length;
1.441 -
1.442 - real_bytes = 0;
1.443 - length = strlen(s_TempSig.sig);
1.444 -
1.445 - for (size_t i=0; i<length; i++)
1.446 - {
1.447 - if (real_bytes >= sizeof(real_sig))
1.448 - {
1.449 - break;
1.450 - }
1.451 - real_sig[real_bytes++] = s_TempSig.sig[i];
1.452 - if (s_TempSig.sig[i] == '\\'
1.453 - && s_TempSig.sig[i+1] == 'x')
1.454 - {
1.455 - if (i + 3 >= length)
1.456 - {
1.457 - continue;
1.458 - }
1.459 - /* Get the hex part */
1.460 - char s_byte[3];
1.461 - int r_byte;
1.462 - s_byte[0] = s_TempSig.sig[i+2];
1.463 - s_byte[1] = s_TempSig.sig[i+3];
1.464 - s_byte[2] = '\0';
1.465 - /* Read it as an integer */
1.466 - sscanf(s_byte, "%x", &r_byte);
1.467 - /* Save the value */
1.468 - real_sig[real_bytes-1] = r_byte;
1.469 - /* Adjust index */
1.470 - i += 3;
1.471 - }
1.472 - }
1.473 -
1.474 - if (real_bytes >= 1)
1.475 - {
1.476 - final_addr = g_MemUtils.FindPattern(addrInBase, real_sig, real_bytes);
1.477 - }
1.478 - }
1.479 -
1.480 -#if defined PLATFORM_LINUX
1.481 -skip_find:
1.482 -#endif
1.483 - sm_trie_replace(m_pSigs, m_offset, final_addr);
1.484 - m_ParseState = PSTATE_GAMEDEFS_SIGNATURES;
1.485 -
1.486 - break;
1.487 - }
1.488 - }
1.489 -
1.490 - return SMCResult_Continue;
1.491 -}
1.492 -
1.493 -bool CGameConfig::Reparse(char *error, size_t maxlength)
1.494 -{
1.495 - SMCError err;
1.496 - SMCStates state = {0, 0};
1.497 -
1.498 - char path[PLATFORM_MAX_PATH];
1.499 - g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "gamedata/%s.txt", m_pFile);
1.500 - /* Backwards compatibility */
1.501 - if (!g_LibSys.PathExists(path))
1.502 - {
1.503 - g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "configs/gamedata/%s.txt", m_pFile);
1.504 - }
1.505 -
1.506 - /* Initialize parse states */
1.507 - m_IgnoreLevel = 0;
1.508 - bShouldBeReadingDefault = true;
1.509 - m_ParseState = PSTATE_NONE;
1.510 - /* Reset cached data */
1.511 - m_pStrings->Reset();
1.512 - sm_trie_clear(m_pOffsets);
1.513 - sm_trie_clear(m_pProps);
1.514 - sm_trie_clear(m_pKeys);
1.515 -
1.516 - if ((err=textparsers->ParseSMCFile(path, this, &state, error, maxlength))
1.517 - != SMCError_Okay)
1.518 - {
1.519 - const char *msg;
1.520 -
1.521 - msg = textparsers->GetSMCErrorString(err);
1.522 -
1.523 - g_Logger.LogError("[SM] Error parsing gameconfig file \"%s\":", path);
1.524 - g_Logger.LogError("[SM] Error %d on line %d, col %d: %s",
1.525 - err,
1.526 - state.line,
1.527 - state.col,
1.528 - msg ? msg : "Unknown error");
1.529 - return false;
1.530 - }
1.531 -
1.532 - return true;
1.533 -}
1.534 -
1.535 -bool CGameConfig::GetOffset(const char *key, int *value)
1.536 -{
1.537 - void *obj;
1.538 -
1.539 - if (!sm_trie_retrieve(m_pOffsets, key, &obj))
1.540 - {
1.541 - return false;
1.542 - }
1.543 -
1.544 - *value = (int)obj;
1.545 -
1.546 - return true;
1.547 -}
1.548 -
1.549 -const char *CGameConfig::GetKeyValue(const char *key)
1.550 -{
1.551 - void *obj;
1.552 - if (!sm_trie_retrieve(m_pKeys, key, &obj))
1.553 - {
1.554 - return NULL;
1.555 - }
1.556 - return m_pStrings->GetString((int)obj);
1.557 -}
1.558 -
1.559 -SendProp *CGameConfig::GetSendProp(const char *key)
1.560 -{
1.561 - SendProp *pProp;
1.562 -
1.563 - if (!sm_trie_retrieve(m_pProps, key, (void **)&pProp))
1.564 - {
1.565 - return NULL;
1.566 - }
1.567 -
1.568 - return pProp;
1.569 -}
1.570 -
1.571 -bool CGameConfig::GetMemSig(const char *key, void **addr)
1.572 -{
1.573 - return sm_trie_retrieve(m_pSigs, key, addr);
1.574 -}
1.575 -
1.576 -void CGameConfig::IncRefCount()
1.577 -{
1.578 - m_RefCount++;
1.579 -}
1.580 -
1.581 -unsigned int CGameConfig::DecRefCount()
1.582 -{
1.583 - m_RefCount--;
1.584 - return m_RefCount;
1.585 -}
1.586 -
1.587 -GameConfigManager::GameConfigManager()
1.588 -{
1.589 - m_pLookup = sm_trie_create();
1.590 -}
1.591 -
1.592 -GameConfigManager::~GameConfigManager()
1.593 -{
1.594 - sm_trie_destroy(m_pLookup);
1.595 -}
1.596 -
1.597 -void GameConfigManager::OnSourceModStartup(bool late)
1.598 -{
1.599 - LoadGameConfigFile("core.games", &g_pGameConf, NULL, 0);
1.600 -
1.601 - strncopy(g_Game, g_SourceMod.GetGameFolderName(), sizeof(g_Game));
1.602 - strncopy(g_GameDesc + 1, SERVER_CALL(GetGameDescription)(), sizeof(g_GameDesc) - 1);
1.603 -
1.604 - KeyValues *pGameInfo = new KeyValues("GameInfo");
1.605 - if (g_HL2.KVLoadFromFile(pGameInfo, basefilesystem, "gameinfo.txt"))
1.606 - {
1.607 - const char *str;
1.608 - if ((str = pGameInfo->GetString("game", NULL)) != NULL)
1.609 - {
1.610 - strncopy(g_GameName + 1, str, sizeof(g_GameName) - 1);
1.611 - }
1.612 - }
1.613 - pGameInfo->deleteThis();
1.614 -}
1.615 -
1.616 -void GameConfigManager::OnSourceModAllInitialized()
1.617 -{
1.618 - /* NOW initialize the game file */
1.619 - CGameConfig *pGameConf = (CGameConfig *)g_pGameConf;
1.620 -
1.621 - char error[255];
1.622 - if (!pGameConf->Reparse(error, sizeof(error)))
1.623 - {
1.624 - /* :TODO: log */
1.625 - }
1.626 -
1.627 - g_ShareSys.AddInterface(NULL, this);
1.628 -}
1.629 -
1.630 -void GameConfigManager::OnSourceModAllShutdown()
1.631 -{
1.632 - CloseGameConfigFile(g_pGameConf);
1.633 -}
1.634 -
1.635 -bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pConfig, char *error, size_t maxlength)
1.636 -{
1.637 - /* A crash was detected during last load - We block the gamedata loading so it hopefully won't happen again */
1.638 - if (g_blockGameDataLoad)
1.639 - {
1.640 - UTIL_Format(error, maxlength, "GameData loaded blocked due to detected crash");
1.641 - return false;
1.642 - }
1.643 -
1.644 - CGameConfig *pConfig;
1.645 -
1.646 - if (sm_trie_retrieve(m_pLookup, file, (void **)&pConfig))
1.647 - {
1.648 - pConfig->IncRefCount();
1.649 - *_pConfig = pConfig;
1.650 - return true;
1.651 - }
1.652 -
1.653 - pConfig = new CGameConfig(file);
1.654 -
1.655 - /* :HACKHACK: Don't parse the main config file */
1.656 - bool retval = true;
1.657 - if (_pConfig != &g_pGameConf)
1.658 - {
1.659 - retval = pConfig->Reparse(error, maxlength);
1.660 - }
1.661 -
1.662 - m_cfgs.push_back(pConfig);
1.663 - sm_trie_insert(m_pLookup, file, pConfig);
1.664 -
1.665 - pConfig->IncRefCount();
1.666 -
1.667 - *_pConfig = pConfig;
1.668 -
1.669 - return retval;
1.670 -}
1.671 -
1.672 -void GameConfigManager::CloseGameConfigFile(IGameConfig *cfg)
1.673 -{
1.674 - CGameConfig *pConfig = (CGameConfig *)cfg;
1.675 -
1.676 - if (pConfig->DecRefCount() == 0)
1.677 - {
1.678 - sm_trie_delete(m_pLookup, pConfig->m_pFile);
1.679 - delete pConfig;
1.680 - }
1.681 -}
1.682 -
1.683 -extern HandleType_t g_GameConfigsType;
1.684 -
1.685 -IGameConfig *GameConfigManager::ReadHandle(Handle_t hndl, IdentityToken_t *ident, HandleError *err)
1.686 -{
1.687 - HandleSecurity sec(ident, g_pCoreIdent);
1.688 - IGameConfig *conf = NULL;
1.689 - HandleError _err = g_HandleSys.ReadHandle(hndl, g_GameConfigsType, &sec, (void **)&conf);
1.690 -
1.691 - if (err)
1.692 - {
1.693 - *err = _err;
1.694 - }
1.695 -
1.696 - return conf;
1.697 -}