From 64455b98523763df7c9476a5ba488b851f130eab Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 14 May 2010 23:35:42 -0700 Subject: [PATCH] Moved gameconf code from core to logic (bug 4406 part 11, r=ds). --HG-- rename : core/GameConfigs.cpp => core/logic/GameConfigs.cpp rename : core/GameConfigs.h => core/logic/GameConfigs.h rename : core/smn_gameconfigs.cpp => core/logic/smn_gameconfigs.cpp --- core/AMBuilder | 2 - core/ConsoleDetours.cpp | 2 +- core/HalfLife2.cpp | 9 +- core/HalfLife2.h | 1 + core/Makefile | 6 +- core/MenuStyle_Radio.cpp | 3 +- core/PlayerManager.cpp | 2 +- core/logic/AMBuilder | 2 + core/{ => logic}/GameConfigs.cpp | 214 +++++++++++---------------- core/{ => logic}/GameConfigs.h | 15 +- core/logic/Makefile | 2 + core/logic/common_logic.cpp | 13 +- core/logic/intercom.h | 16 +- core/{ => logic}/smn_gameconfigs.cpp | 18 +-- core/logic/stringutil.cpp | 33 +++++ core/logic/stringutil.h | 1 + core/logic_bridge.cpp | 60 +++++++- core/logic_bridge.h | 4 +- core/sm_globals.h | 2 - core/sm_stringutil.cpp | 32 ---- core/sm_stringutil.h | 1 - core/smn_entities.cpp | 3 +- core/smn_hudtext.cpp | 3 +- core/sourcemod.cpp | 4 +- public/IGameHelpers.h | 10 +- 25 files changed, 254 insertions(+), 204 deletions(-) rename core/{ => logic}/GameConfigs.cpp (77%) rename core/{ => logic}/GameConfigs.h (93%) rename core/{ => logic}/smn_gameconfigs.cpp (84%) diff --git a/core/AMBuilder b/core/AMBuilder index 8953811b..fb5e768d 100644 --- a/core/AMBuilder +++ b/core/AMBuilder @@ -33,7 +33,6 @@ for i in SM.sdkInfo: 'smn_nextmap.cpp', 'sourcemm_api.cpp', 'ChatTriggers.cpp', - 'GameConfigs.cpp', 'NativeOwner.cpp', 'smn_filesystem.cpp', 'smn_player.cpp', @@ -47,7 +46,6 @@ for i in SM.sdkInfo: 'ConVarManager.cpp', 'LibrarySys.cpp', 'PlayerManager.cpp', - 'smn_gameconfigs.cpp', 'TimerSys.cpp', 'CoreConfig.cpp', 'Logger.cpp', diff --git a/core/ConsoleDetours.cpp b/core/ConsoleDetours.cpp index ce1722ea..49c5d8cb 100644 --- a/core/ConsoleDetours.cpp +++ b/core/ConsoleDetours.cpp @@ -44,7 +44,7 @@ #include "Logger.h" #include "compat_wrappers.h" #include "ConsoleDetours.h" -#include "GameConfigs.h" +#include #include "sm_stringutil.h" #include "ConCmdManager.h" #include "HalfLife2.h" diff --git a/core/HalfLife2.cpp b/core/HalfLife2.cpp index 6ba89d70..5badde01 100644 --- a/core/HalfLife2.cpp +++ b/core/HalfLife2.cpp @@ -35,9 +35,10 @@ #include "UserMessages.h" #include "PlayerManager.h" #include "sm_stringutil.h" -#include "GameConfigs.h" +#include #include #include +#include "logic_bridge.h" CHalfLife2 g_HL2; ConVar *sv_lan = NULL; @@ -888,3 +889,9 @@ void *CHalfLife2::GetGlobalEntityList() { return g_EntList; } + +int CHalfLife2::GetSendPropOffset(SendProp *prop) +{ + return prop->GetOffset(); +} + diff --git a/core/HalfLife2.h b/core/HalfLife2.h index 6dfd7689..bf8f876f 100644 --- a/core/HalfLife2.h +++ b/core/HalfLife2.h @@ -135,6 +135,7 @@ public: //IGameHelpers CEntInfo *LookupEntity(int entIndex); cell_t EntityToBCompatRef(CBaseEntity *pEntity); void *GetGlobalEntityList(); + int GetSendPropOffset(SendProp *prop); public: void AddToFakeCliCmdQueue(int client, int userid, const char *cmd); void ProcessFakeCliCmdQueue(); diff --git a/core/Makefile b/core/Makefile index 60b82906..0f0f0768 100644 --- a/core/Makefile +++ b/core/Makefile @@ -15,7 +15,7 @@ MMSOURCE17 = ../../mmsource-central ##################################### OBJECTS = AdminCache.cpp CDataPack.cpp ConCmdManager.cpp ConVarManager.cpp CoreConfig.cpp \ - Database.cpp DebugReporter.cpp EventManager.cpp GameConfigs.cpp HalfLife2.cpp Logger.cpp \ + Database.cpp DebugReporter.cpp EventManager.cpp HalfLife2.cpp Logger.cpp \ PlayerManager.cpp TimerSys.cpp UserMessages.cpp \ sm_autonatives.cpp sm_srvcmds.cpp sm_stringutil.cpp sm_trie.cpp \ sourcemm_api.cpp sourcemod.cpp MenuStyle_Base.cpp MenuStyle_Valve.cpp MenuManager.cpp \ @@ -23,8 +23,8 @@ OBJECTS = AdminCache.cpp CDataPack.cpp ConCmdManager.cpp ConVarManager.cpp CoreC frame_hooks.cpp concmd_cleaner.cpp NextMap.cpp \ NativeOwner.cpp logic_bridge.cpp ConsoleDetours.cpp OBJECTS += smn_bitbuffer.cpp smn_console.cpp smn_core.cpp \ - smn_datapacks.cpp smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \ - smn_filesystem.cpp smn_gameconfigs.cpp smn_halflife.cpp \ + smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \ + smn_filesystem.cpp smn_halflife.cpp \ smn_keyvalues.cpp smn_player.cpp \ smn_usermsgs.cpp smn_menus.cpp smn_vector.cpp \ smn_hudtext.cpp smn_nextmap.cpp diff --git a/core/MenuStyle_Radio.cpp b/core/MenuStyle_Radio.cpp index 8da01b1c..de456e71 100644 --- a/core/MenuStyle_Radio.cpp +++ b/core/MenuStyle_Radio.cpp @@ -32,11 +32,12 @@ #include "MenuStyle_Radio.h" #include "sm_stringutil.h" #include "UserMessages.h" -#include "GameConfigs.h" +#include #include "PlayerManager.h" #if defined MENU_DEBUG #include "Logger.h" #endif +#include "logic_bridge.h" extern const char *g_RadioNumTable[]; CRadioStyle g_RadioMenuStyle; diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index 03ef9de5..0db11a83 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -44,7 +44,7 @@ #include "HalfLife2.h" #include #include -#include "GameConfigs.h" +#include #include "ExtensionSys.h" #include #include "ConsoleDetours.h" diff --git a/core/logic/AMBuilder b/core/logic/AMBuilder index 91bdee80..c51de047 100644 --- a/core/logic/AMBuilder +++ b/core/logic/AMBuilder @@ -42,6 +42,8 @@ files = [ 'smn_string.cpp', 'smn_handles.cpp', 'smn_datapacks.cpp', + 'smn_gameconfigs.cpp', + 'GameConfigs.cpp', 'sm_crc32.cpp' ] if AMBuild.target['platform'] == 'windows': diff --git a/core/GameConfigs.cpp b/core/logic/GameConfigs.cpp similarity index 77% rename from core/GameConfigs.cpp rename to core/logic/GameConfigs.cpp index 46a7900b..e3b129a3 100644 --- a/core/GameConfigs.cpp +++ b/core/logic/GameConfigs.cpp @@ -27,24 +27,28 @@ * or . */ +#include "common_logic.h" #include #include +#include +#include #include "GameConfigs.h" -#include "sm_stringutil.h" -#include "sourcemod.h" -#include "sourcemm_api.h" -#include "HalfLife2.h" -#include "Logger.h" -#include "ShareSys.h" -#include "LibrarySys.h" -#include "HandleSys.h" +#include "stringutil.h" +#include +#include +#include #include -#include "logic_bridge.h" +#include +#include "common_logic.h" +#include "sm_crc32.h" +#include "MemoryUtils.h" #if defined PLATFORM_LINUX #include #endif +using namespace SourceHook; + GameConfigManager g_GameConfigs; IGameConfig *g_pGameConf = NULL; static char g_Game[256]; @@ -108,35 +112,13 @@ static bool DoesGameMatch(const char *value) static bool DoesEngineMatch(const char *value) { -#if SOURCE_ENGINE == SE_EPISODEONE - if (strcmp(value, "original") == 0) -#elif SOURCE_ENGINE == SE_DARKMESSIAH - if (strcmp(value, "darkmessiah") == 0) -#elif SOURCE_ENGINE == SE_ORANGEBOX - if (strcmp(value, "orangebox") == 0) -#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE - if (strcmp(value, "orangebox_valve") == 0) -#elif SOURCE_ENGINE == SE_LEFT4DEAD - if (strcmp(value, "left4dead") == 0) -#elif SOURCE_ENGINE == SE_LEFT4DEAD2 - if (strcmp(value, "left4dead2") == 0) -#else -#error "Unknown engine type" -#endif - { - return true; - } - return false; + return strcmp(value, smcore.GetSourceEngineName()) == 0; } CGameConfig::CGameConfig(const char *file) { strncopy(m_File, file, sizeof(m_File)); - m_pOffsets = sm_trie_create(); - m_pProps = sm_trie_create(); - m_pKeys = sm_trie_create(); m_pAddresses = new KTrie(); - m_pSigs = sm_trie_create(); m_pStrings = new BaseStringTable(512); m_RefCount = 0; @@ -146,11 +128,7 @@ CGameConfig::CGameConfig(const char *file) CGameConfig::~CGameConfig() { - sm_trie_destroy(m_pOffsets); - sm_trie_destroy(m_pProps); - sm_trie_destroy(m_pKeys); delete m_pAddresses; - sm_trie_destroy(m_pSigs); delete m_pStrings; } @@ -259,17 +237,17 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n error[0] = '\0'; if (strcmp(name, "server") != 0) { - UTIL_Format(error, sizeof(error), "Unrecognized library \"%s\"", name); + smcore.Format(error, sizeof(error), "Unrecognized library \"%s\"", name); } else if (!s_ServerBinCRC_Ok) { FILE *fp; char path[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "bin/" PLATFORM_SERVER_BINARY); + g_pSM->BuildPath(Path_Game, path, sizeof(path), "bin/" PLATFORM_SERVER_BINARY); if ((fp = fopen(path, "rb")) == NULL) { - UTIL_Format(error, sizeof(error), "Could not open binary: %s", path); + smcore.Format(error, sizeof(error), "Could not open binary: %s", path); } else { size_t size; void *buffer; @@ -289,8 +267,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n if (error[0] != '\0') { m_IgnoreLevel = 1; - g_Logger.LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile); - g_Logger.LogError("[SM] %s", error); + smcore.LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile); + smcore.LogError("[SM] %s", error); } else { m_ParseState = PSTATE_GAMEDEFS_CRC_BINARY; } @@ -323,8 +301,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n { if (strcmp(name, "linux") != 0 && strcmp(name, "windows") != 0) { - g_Logger.LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile); - g_Logger.LogError("[SM] Unrecognized platform \"%s\"", name); + smcore.LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile); + smcore.LogError("[SM] Unrecognized platform \"%s\"", name); } m_IgnoreLevel = 1; } @@ -364,12 +342,10 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key } else if (strcmp(key, "prop") == 0) { strncopy(m_Prop, value, sizeof(m_Prop)); } else if (strcmp(key, PLATFORM_NAME) == 0) { - int val = atoi(value); - sm_trie_replace(m_pOffsets, m_offset, (void *)val); + m_Offsets.replace(m_offset, atoi(value)); } } else if (m_ParseState == PSTATE_GAMEDEFS_KEYS) { - int id = m_pStrings->AddString(value); - sm_trie_replace(m_pKeys, key, (void *)id); + m_Keys.replace(key, m_pStrings->AddString(value)); } else if (m_ParseState == PSTATE_GAMEDEFS_SUPPORTED) { if (strcmp(key, "game") == 0) { @@ -424,7 +400,7 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key } else { - g_Logger.LogError("[SM] Error parsing Address \"%s\", does not support more than %d read offsets (gameconf \"%s\")", m_Address, limit, m_CurFile); + smcore.LogError("[SM] Error parsing Address \"%s\", does not support more than %d read offsets (gameconf \"%s\")", m_Address, limit, m_CurFile); } } else if (strcmp(key, "signature") == 0) { strncopy(m_AddressSignature, value, sizeof(m_AddressSignature)); @@ -481,18 +457,18 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states) if (m_Class[0] != '\0' && m_Prop[0] != '\0') { - SendProp *pProp = g_HL2.FindInSendTable(m_Class, m_Prop); + SendProp *pProp = gamehelpers->FindInSendTable(m_Class, m_Prop); if (pProp) { - int val = pProp->GetOffset(); - sm_trie_replace(m_pOffsets, m_offset, (void *)val); - sm_trie_replace(m_pProps, m_offset, pProp); + int val = gamehelpers->GetSendPropOffset(pProp); + m_Offsets.replace(m_offset, val); + m_Props.replace(m_offset, pProp); } else { /* Check if it's a non-default game and no offsets exist */ if (((strcmp(m_Game, "*") != 0) && strcmp(m_Game, "#default") != 0) - && (!sm_trie_retrieve(m_pOffsets, m_offset, NULL))) + && (!m_Offsets.retrieve(m_offset))) { - g_Logger.LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")", + smcore.LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")", m_Class, m_Prop, m_CurFile, @@ -536,14 +512,14 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states) void *addrInBase = NULL; if (strcmp(s_TempSig.library, "server") == 0) { - addrInBase = (void *)g_SMAPI->GetServerFactory(false); + addrInBase = smcore.serverFactory; } else if (strcmp(s_TempSig.library, "engine") == 0) { - addrInBase = (void *)g_SMAPI->GetEngineFactory(false); + addrInBase = smcore.engineFactory; } void *final_addr = NULL; if (addrInBase == NULL) { - g_Logger.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")", + smcore.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")", s_TempSig.library, m_CurFile); } else { @@ -557,19 +533,18 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states) void *handle = dlopen(info.dli_fname, RTLD_NOW); if (handle) { -#if (SOURCE_ENGINE == SE_ORANGEBOXVALVE) || (SOURCE_ENGINE == SE_LEFT4DEAD2) - final_addr = memutils->ResolveSymbol(handle, &s_TempSig.sig[1]); -#else - final_addr = dlsym(handle, &s_TempSig.sig[1]); -#endif + if (smcore.SymbolsAreHidden()) + final_addr = g_MemUtils.ResolveSymbol(handle, &s_TempSig.sig[1]); + else + final_addr = dlsym(handle, &s_TempSig.sig[1]); dlclose(handle); } else { - g_Logger.LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")", + smcore.LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")", s_TempSig.library, m_File); } } else { - g_Logger.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", + smcore.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", s_TempSig.library, m_File); } @@ -591,14 +566,14 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states) if (real_bytes >= 1) { - final_addr = memutils->FindPattern(addrInBase, (char*)real_sig, real_bytes); + final_addr = g_MemUtils.FindPattern(addrInBase, (char*)real_sig, real_bytes); } } #if defined PLATFORM_LINUX skip_find: #endif - sm_trie_replace(m_pSigs, m_offset, final_addr); + m_Sigs.replace(m_offset, final_addr); m_ParseState = PSTATE_GAMEDEFS_SIGNATURES; break; @@ -614,12 +589,12 @@ skip_find: if (m_Address[0] == '\0') { - g_Logger.LogError("[SM] Address sections must have names (gameconf \"%s\")", m_CurFile); + smcore.LogError("[SM] Address sections must have names (gameconf \"%s\")", m_CurFile); break; } if (m_AddressSignature[0] == '\0') { - g_Logger.LogError("[SM] Address section for \"%s\" did not specify a signature (gameconf \"%s\")", m_Address, m_CurFile); + smcore.LogError("[SM] Address section for \"%s\" did not specify a signature (gameconf \"%s\")", m_Address, m_CurFile); break; } @@ -769,19 +744,19 @@ bool CGameConfig::Reparse(char *error, size_t maxlength) { /* Reset cached data */ m_pStrings->Reset(); - sm_trie_clear(m_pOffsets); - sm_trie_clear(m_pProps); - sm_trie_clear(m_pKeys); + m_Offsets.clear(); + m_Props.clear(); + m_Keys.clear(); m_pAddresses->clear(); char path[PLATFORM_MAX_PATH]; /* See if we can use the extended gamedata format. */ - g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "gamedata/%s/master.games.txt", m_File); - if (!g_LibSys.PathExists(path)) + g_pSM->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s/master.games.txt", m_File); + if (!libsys->PathExists(path)) { /* Nope, use the old mechanism. */ - UTIL_Format(path, sizeof(path), "%s.txt", m_File); + smcore.Format(path, sizeof(path), "%s.txt", m_File); return EnterFile(path, error, maxlength); } @@ -796,8 +771,8 @@ bool CGameConfig::Reparse(char *error, size_t maxlength) { const char *msg = textparsers->GetSMCErrorString(err); - g_Logger.LogError("[SM] Error parsing master gameconf file \"%s\":", path); - g_Logger.LogError("[SM] Error %d on line %d, col %d: %s", + smcore.LogError("[SM] Error parsing master gameconf file \"%s\":", path); + smcore.LogError("[SM] Error %d on line %d, col %d: %s", err, state.line, state.col, @@ -809,7 +784,7 @@ bool CGameConfig::Reparse(char *error, size_t maxlength) List::iterator iter; for (iter = fileList.begin(); iter != fileList.end(); iter++) { - UTIL_Format(path, sizeof(path), "%s/%s", m_File, (*iter).c_str()); + smcore.Format(path, sizeof(path), "%s/%s", m_File, (*iter).c_str()); if (!EnterFile(path, error, maxlength)) { return false; @@ -817,8 +792,8 @@ bool CGameConfig::Reparse(char *error, size_t maxlength) } /* Parse the contents of the 'custom' directory */ - g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "gamedata/%s/custom", m_File); - IDirectory *customDir = g_LibSys.OpenDirectory(path); + g_pSM->BuildPath(Path_SM, path, sizeof(path), "gamedata/%s/custom", m_File); + IDirectory *customDir = libsys->OpenDirectory(path); if (!customDir) { @@ -843,17 +818,17 @@ bool CGameConfig::Reparse(char *error, size_t maxlength) continue; } - UTIL_Format(path, sizeof(path), "%s/custom/%s", m_File, curFile); + smcore.Format(path, sizeof(path), "%s/custom/%s", m_File, curFile); if (!EnterFile(path, error, maxlength)) { - g_LibSys.CloseDirectory(customDir); + libsys->CloseDirectory(customDir); return false; } customDir->NextEntry(); } - g_LibSys.CloseDirectory(customDir); + libsys->CloseDirectory(customDir); return true; } @@ -862,7 +837,7 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength) SMCError err; SMCStates state = {0, 0}; - g_SourceMod.BuildPath(Path_SM, m_CurFile, sizeof(m_CurFile), "gamedata/%s", file); + g_pSM->BuildPath(Path_SM, m_CurFile, sizeof(m_CurFile), "gamedata/%s", file); /* Initialize parse states */ m_IgnoreLevel = 0; @@ -876,8 +851,8 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength) msg = textparsers->GetSMCErrorString(err); - g_Logger.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile); - g_Logger.LogError("[SM] Error %d on line %d, col %d: %s", + smcore.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile); + smcore.LogError("[SM] Error %d on line %d, col %d: %s", err, state.line, state.col, @@ -899,26 +874,20 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength) bool CGameConfig::GetOffset(const char *key, int *value) { - void *obj; - - if (!sm_trie_retrieve(m_pOffsets, key, &obj)) - { + int *pvalue; + if ((pvalue = m_Offsets.retrieve(key)) == NULL) return false; - } - *value = (int)obj; - + *value = *pvalue; return true; } const char *CGameConfig::GetKeyValue(const char *key) { - void *obj; - if (!sm_trie_retrieve(m_pKeys, key, &obj)) - { + int *pkey; + if ((pkey = m_Keys.retrieve(key)) == NULL) return NULL; - } - return m_pStrings->GetString((int)obj); + return m_pStrings->GetString(*pkey); } //memory addresses below 0x10000 are automatically considered invalid for dereferencing @@ -959,6 +928,11 @@ bool CGameConfig::GetAddress(const char *key, void **retaddr) return true; } +static inline unsigned min(unsigned a, unsigned b) +{ + return a <= b ? a : b; +} + CGameConfig::AddressConf::AddressConf(char *sigName, unsigned sigLength, unsigned readCount, int *read) { unsigned readLimit = min(readCount, sizeof(this->read) / sizeof(this->read[0])); @@ -970,19 +944,21 @@ CGameConfig::AddressConf::AddressConf(char *sigName, unsigned sigLength, unsigne SendProp *CGameConfig::GetSendProp(const char *key) { - SendProp *pProp; + SendProp **pProp; - if (!sm_trie_retrieve(m_pProps, key, (void **)&pProp)) - { + if ((pProp = m_Props.retrieve(key)) == NULL) return NULL; - } - return pProp; + return *pProp; } bool CGameConfig::GetMemSig(const char *key, void **addr) { - return sm_trie_retrieve(m_pSigs, key, addr); + void **paddr; + if ((paddr = m_Sigs.retrieve(key)) == NULL) + return false; + *addr = *paddr; + return true; } void CGameConfig::IncRefCount() @@ -998,31 +974,19 @@ unsigned int CGameConfig::DecRefCount() GameConfigManager::GameConfigManager() { - m_pLookup = sm_trie_create(); } GameConfigManager::~GameConfigManager() { - sm_trie_destroy(m_pLookup); } void GameConfigManager::OnSourceModStartup(bool late) { LoadGameConfigFile("core.games", &g_pGameConf, NULL, 0); - strncopy(g_Game, g_SourceMod.GetGameFolderName(), sizeof(g_Game)); - strncopy(g_GameDesc + 1, SERVER_CALL(GetGameDescription)(), sizeof(g_GameDesc) - 1); - - KeyValues *pGameInfo = new KeyValues("GameInfo"); - if (g_HL2.KVLoadFromFile(pGameInfo, basefilesystem, "gameinfo.txt")) - { - const char *str; - if ((str = pGameInfo->GetString("game", NULL)) != NULL) - { - strncopy(g_GameName + 1, str, sizeof(g_GameName) - 1); - } - } - pGameInfo->deleteThis(); + strncopy(g_Game, g_pSM->GetGameFolderName(), sizeof(g_Game)); + strncopy(g_GameDesc + 1, smcore.GetGameDescription(), sizeof(g_GameDesc) - 1); + smcore.GetGameName(g_GameName + 1, sizeof(g_GameName) - 1); } void GameConfigManager::OnSourceModAllInitialized() @@ -1036,7 +1000,7 @@ void GameConfigManager::OnSourceModAllInitialized() /* :TODO: log */ } - g_ShareSys.AddInterface(NULL, this); + sharesys->AddInterface(NULL, this); } void GameConfigManager::OnSourceModAllShutdown() @@ -1056,9 +1020,11 @@ bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pCon #endif CGameConfig *pConfig; + CGameConfig **ppConfig; - if (sm_trie_retrieve(m_pLookup, file, (void **)&pConfig)) + if ((ppConfig = m_Lookup.retrieve(file)) != NULL) { + pConfig = *ppConfig; pConfig->IncRefCount(); *_pConfig = pConfig; return true; @@ -1074,7 +1040,7 @@ bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pCon } m_cfgs.push_back(pConfig); - sm_trie_insert(m_pLookup, file, pConfig); + m_Lookup.insert(file, pConfig); pConfig->IncRefCount(); @@ -1089,18 +1055,18 @@ void GameConfigManager::CloseGameConfigFile(IGameConfig *cfg) if (pConfig->DecRefCount() == 0) { - sm_trie_delete(m_pLookup, pConfig->m_File); + m_Lookup.remove(pConfig->m_File); delete pConfig; } } -extern HandleType_t g_GameConfigsType; +extern Handle_t g_GameConfigsType; IGameConfig *GameConfigManager::ReadHandle(Handle_t hndl, IdentityToken_t *ident, HandleError *err) { HandleSecurity sec(ident, g_pCoreIdent); IGameConfig *conf = NULL; - HandleError _err = g_HandleSys.ReadHandle(hndl, g_GameConfigsType, &sec, (void **)&conf); + HandleError _err = handlesys->ReadHandle(hndl, g_GameConfigsType, &sec, (void **)&conf); if (err) { diff --git a/core/GameConfigs.h b/core/logic/GameConfigs.h similarity index 93% rename from core/GameConfigs.h rename to core/logic/GameConfigs.h index 067e25a3..d24785d7 100644 --- a/core/GameConfigs.h +++ b/core/logic/GameConfigs.h @@ -32,13 +32,12 @@ #ifndef _INCLUDE_SOURCEMOD_CGAMECONFIGS_H_ #define _INCLUDE_SOURCEMOD_CGAMECONFIGS_H_ +#include "common_logic.h" #include #include #include -#include "sm_trie.h" -#include "sm_globals.h" #include "sm_memtable.h" -#include "sm_trie_tpl.h" +#include using namespace SourceMod; using namespace SourceHook; @@ -73,10 +72,10 @@ private: BaseStringTable *m_pStrings; char m_File[PLATFORM_MAX_PATH]; char m_CurFile[PLATFORM_MAX_PATH]; - Trie *m_pOffsets; - Trie *m_pProps; - Trie *m_pKeys; - Trie *m_pSigs; + KTrie m_Offsets; + KTrie m_Props; + KTrie m_Keys; + KTrie m_Sigs; unsigned int m_RefCount; /* Parse states */ int m_ParseState; @@ -137,7 +136,7 @@ public: //SMGlobalClass void OnSourceModAllShutdown(); private: List m_cfgs; - Trie *m_pLookup; + KTrie m_Lookup; public: KTrie m_customHandlers; }; diff --git a/core/logic/Makefile b/core/logic/Makefile index 4b1a1dca..3be2e956 100644 --- a/core/logic/Makefile +++ b/core/logic/Makefile @@ -38,6 +38,8 @@ OBJECTS = \ smn_string.cpp \ smn_handles.cpp \ smn_datapacks.cpp \ + smn_gameconfigs.cpp \ + GameConfigs.cpp \ smn_players.cpp ############################################## diff --git a/core/logic/common_logic.cpp b/core/logic/common_logic.cpp index 56b404b1..518fb8c7 100644 --- a/core/logic/common_logic.cpp +++ b/core/logic/common_logic.cpp @@ -40,6 +40,7 @@ #include "MemoryUtils.h" #include "stringutil.h" #include "Translator.h" +#include "GameConfigs.h" sm_core_t smcore; IHandleSys *handlesys; @@ -64,19 +65,24 @@ static void AddCorePhraseFile(const char *filename) g_pCorePhrases->AddPhraseFile("antiflood.phrases"); } +static IGameConfig *GetCoreGameConfig() +{ + return g_pGameConf; +} + static sm_logic_t logic = { NULL, g_pThreader, sm_profiler, - &g_MemUtils, &g_Translator, - UTIL_CRC32, stristr, CoreTranslate, AddCorePhraseFile, UTIL_ReplaceAll, - UTIL_ReplaceEx + UTIL_ReplaceEx, + UTIL_DecodeHexString, + GetCoreGameConfig }; static void logic_init(const sm_core_t* core, sm_logic_t* _logic) @@ -99,6 +105,7 @@ static void logic_init(const sm_core_t* core, sm_logic_t* _logic) timersys = core->timersys; playerhelpers = core->playerhelpers; adminsys = core->adminsys; + gamehelpers = core->gamehelpers; } PLATFORM_EXTERN_C ITextParsers *get_textparsers() diff --git a/core/logic/intercom.h b/core/logic/intercom.h index 341cb104..b2f622c1 100644 --- a/core/logic/intercom.h +++ b/core/logic/intercom.h @@ -42,7 +42,7 @@ using namespace SourceMod; * Add 1 to the RHS of this expression to bump the intercom file * This is to prevent mismatching core/logic binaries */ -#define SM_LOGIC_MAGIC (0x0F47C0DE - 13) +#define SM_LOGIC_MAGIC (0x0F47C0DE - 14) #if defined SM_LOGIC class IVEngineServer @@ -66,11 +66,11 @@ namespace SourceMod class IForwardManager; class ITimerSystem; class IPlayerManager; - class IMemoryUtils; class IAdminSystem; class IGameHelpers; class IPhraseCollection; class ITranslator; + class IGameConfig; } class IVEngineServer; @@ -98,7 +98,7 @@ struct sm_core_t ITimerSystem *timersys; IPlayerManager *playerhelpers; IAdminSystem *adminsys; - IGameHelpers *gamehelers; + IGameHelpers *gamehelpers; /* Functions */ void (*AddNatives)(sp_nativeinfo_t* nlist); ConVar * (*FindConVar)(const char*); @@ -111,8 +111,14 @@ struct sm_core_t bool (*gnprintf)(char *, size_t, const char *, IPhraseCollection *, void **, unsigned int, unsigned int &, size_t *, const char **); size_t (*atcprintf)(char *, size_t, const char *, IPluginContext *, const cell_t *, int *); + bool (*GetGameName)(char *buffer, size_t maxlength); + const char * (*GetGameDescription)(); + const char * (*GetSourceEngineName)(); + bool (*SymbolsAreHidden)(); /* Data */ ServerGlobals *serverGlobals; + void * serverFactory; + void * engineFactory; }; struct sm_logic_t @@ -120,14 +126,14 @@ struct sm_logic_t SMGlobalClass *head; IThreader *threader; IProfiler *profiler; - IMemoryUtils *memutils; ITranslator *translator; - unsigned int (*CRC32)(const void *, size_t); const char *(*stristr)(const char *, const char *); bool (*CoreTranslate)(char *, size_t, const char *, unsigned int, size_t *, ...); void (*AddCorePhraseFile)(const char *filename); unsigned int (*ReplaceAll)(char*, size_t, const char *, const char *, bool); char *(*ReplaceEx)(char *, size_t, const char *, size_t, const char *, size_t, bool); + size_t (*DecodeHexString)(unsigned char *, size_t, const char *); + IGameConfig * (*GetCoreGameConfig)(); }; typedef void (*LogicInitFunction)(const sm_core_t *core, sm_logic_t *logic); diff --git a/core/smn_gameconfigs.cpp b/core/logic/smn_gameconfigs.cpp similarity index 84% rename from core/smn_gameconfigs.cpp rename to core/logic/smn_gameconfigs.cpp index aa1a7aa4..eff28ae2 100644 --- a/core/smn_gameconfigs.cpp +++ b/core/logic/smn_gameconfigs.cpp @@ -29,24 +29,24 @@ * Version: $Id$ */ -#include "sourcemod.h" -#include "HandleSys.h" +#include "common_logic.h" +#include #include "GameConfigs.h" HandleType_t g_GameConfigsType; class GameConfigsNatives : public IHandleTypeDispatch, - public SourceModBase + public SMGlobalClass { public: void OnSourceModAllInitialized() { - g_GameConfigsType = g_HandleSys.CreateType("GameConfigs", this, 0, NULL, NULL, g_pCoreIdent, NULL); + g_GameConfigsType = handlesys->CreateType("GameConfigs", this, 0, NULL, NULL, g_pCoreIdent, NULL); } void OnSourceModShutdown() { - g_HandleSys.RemoveType(g_GameConfigsType, g_pCoreIdent); + handlesys->RemoveType(g_GameConfigsType, g_pCoreIdent); g_GameConfigsType = 0; } void OnHandleDestroy(HandleType_t type, void *object) @@ -67,7 +67,7 @@ static cell_t smn_LoadGameConfigFile(IPluginContext *pCtx, const cell_t *params) return pCtx->ThrowNativeError("Unable to open %s: %s", filename, error); } - return g_HandleSys.CreateHandle(g_GameConfigsType, gc, pCtx->GetIdentity(), g_pCoreIdent, NULL); + return handlesys->CreateHandle(g_GameConfigsType, gc, pCtx->GetIdentity(), g_pCoreIdent, NULL); } static cell_t smn_GameConfGetOffset(IPluginContext *pCtx, const cell_t *params) @@ -80,7 +80,7 @@ static cell_t smn_GameConfGetOffset(IPluginContext *pCtx, const cell_t *params) sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; - if ((herr=g_HandleSys.ReadHandle(hndl, g_GameConfigsType, &sec, (void **)&gc)) + if ((herr=handlesys->ReadHandle(hndl, g_GameConfigsType, &sec, (void **)&gc)) != HandleError_None) { return pCtx->ThrowNativeError("Invalid game config handle %x (error %d)", hndl, herr); @@ -108,7 +108,7 @@ static cell_t smn_GameConfGetKeyValue(IPluginContext *pCtx, const cell_t *params sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; - if ((herr=g_HandleSys.ReadHandle(hndl, g_GameConfigsType, &sec, (void **)&gc)) + if ((herr=handlesys->ReadHandle(hndl, g_GameConfigsType, &sec, (void **)&gc)) != HandleError_None) { return pCtx->ThrowNativeError("Invalid game config handle %x (error %d)", hndl, herr); @@ -139,7 +139,7 @@ static cell_t smn_GameConfGetAddress(IPluginContext *pCtx, const cell_t *params) sec.pOwner = NULL; sec.pIdentity = g_pCoreIdent; - if ((herr=g_HandleSys.ReadHandle(hndl, g_GameConfigsType, &sec, (void **)&gc)) + if ((herr=handlesys->ReadHandle(hndl, g_GameConfigsType, &sec, (void **)&gc)) != HandleError_None) { return pCtx->ThrowNativeError("Invalid game config handle %x (error %d)", hndl, herr); diff --git a/core/logic/stringutil.cpp b/core/logic/stringutil.cpp index 7518dd98..d6ca9294 100644 --- a/core/logic/stringutil.cpp +++ b/core/logic/stringutil.cpp @@ -30,6 +30,7 @@ */ #include +#include #include #include #include "stringutil.h" @@ -270,3 +271,35 @@ char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t se return NULL; } +size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr) +{ + size_t written = 0; + size_t length = strlen(hexstr); + + for (size_t i = 0; i < length; i++) + { + if (written >= maxlength) + break; + buffer[written++] = hexstr[i]; + if (hexstr[i] == '\\' && hexstr[i + 1] == 'x') + { + if (i + 3 >= length) + continue; + /* Get the hex part. */ + char s_byte[3]; + int r_byte; + s_byte[0] = hexstr[i + 2]; + s_byte[1] = hexstr[i + 3]; + s_byte[2] = '\0'; + /* Read it as an integer */ + sscanf(s_byte, "%x", &r_byte); + /* Save the value */ + buffer[written - 1] = r_byte; + /* Adjust index */ + i += 3; + } + } + + return written; +} + diff --git a/core/logic/stringutil.h b/core/logic/stringutil.h index 4d07f069..6ff04641 100644 --- a/core/logic/stringutil.h +++ b/core/logic/stringutil.h @@ -38,6 +38,7 @@ unsigned int UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search const char *replace, bool caseSensitive = true); char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t searchLen, const char *replace, size_t replaceLen, bool caseSensitive = true); +size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr); #endif /* _INCLUDE_SOURCEMOD_COMMON_STRINGUTIL_H_ */ diff --git a/core/logic_bridge.cpp b/core/logic_bridge.cpp index d6b3525a..d8d625f7 100644 --- a/core/logic_bridge.cpp +++ b/core/logic_bridge.cpp @@ -55,8 +55,6 @@ static LogicInitFunction logic_init_fn; IThreader *g_pThreader; ITextParsers *textparsers; -SM_FN_CRC32 UTIL_CRC32; -IMemoryUtils *memutils; sm_logic_t logicore; ITranslator *translator; @@ -109,6 +107,56 @@ static const char *get_cvar_string(ConVar* cvar) return cvar->GetString(); } +static bool get_game_name(char *buffer, size_t maxlength) +{ + KeyValues *pGameInfo = new KeyValues("GameInfo"); + if (g_HL2.KVLoadFromFile(pGameInfo, basefilesystem, "gameinfo.txt")) + { + const char *str; + if ((str = pGameInfo->GetString("game", NULL)) != NULL) + { + strncopy(buffer, str, maxlength); + return true; + } + } + pGameInfo->deleteThis(); + return false; +} + +static const char *get_game_description() +{ + return SERVER_CALL(GetGameDescription)(); +} + +static const char *get_source_engine_name() +{ +#if !defined SOURCE_ENGINE +# error "Unknown engine type" +#endif +#if SOURCE_ENGINE == SE_EPISODEONE + return "original"; +#elif SOURCE_ENGINE == SE_DARKMESSIAH + return "darkmessiah"; +#elif SOURCE_ENGINE == SE_ORANGEBOX + return "orangebox"; +#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE + return "orangebox_valve"; +#elif SOURCE_ENGINE == SE_LEFT4DEAD + return "left4dead"; +#elif SOURCE_ENGINE == SE_LEFT4DEAD2 + return "left4dead2"; +#endif +} + +static bool symbols_are_hidden() +{ +#if (SOURCE_ENGINE == SE_ORANGEBOXVALVE) || (SOURCE_ENGINE == SE_LEFT4DEAD2) + return true; +#else + return false; +#endif +} + static ServerGlobals serverGlobals; static sm_core_t core_bridge = @@ -138,6 +186,10 @@ static sm_core_t core_bridge = generate_error, gnprintf, atcprintf, + get_game_name, + get_game_description, + get_source_engine_name, + symbols_are_hidden, &serverGlobals }; @@ -148,6 +200,8 @@ void InitLogicBridge() serverGlobals.interval_per_tick = &gpGlobals->interval_per_tick; core_bridge.core_ident = g_pCoreIdent; + core_bridge.engineFactory = (void *)g_SMAPI->GetEngineFactory(false); + core_bridge.serverFactory = (void *)g_SMAPI->GetServerFactory(false); logic_init_fn(&core_bridge, &logicore); /* Add SMGlobalClass instances */ @@ -161,8 +215,6 @@ void InitLogicBridge() g_pThreader = logicore.threader; g_pSourcePawn2->SetProfiler(logicore.profiler); - UTIL_CRC32 = logicore.CRC32; - memutils = logicore.memutils; translator = logicore.translator; } diff --git a/core/logic_bridge.h b/core/logic_bridge.h index 1b2e3f1d..efc22a5d 100644 --- a/core/logic_bridge.h +++ b/core/logic_bridge.h @@ -39,11 +39,9 @@ void ShutdownLogicBridge(); struct sm_logic_t; -typedef unsigned int (*SM_FN_CRC32)(const void *, size_t); - -extern SM_FN_CRC32 UTIL_CRC32; extern sm_logic_t logicore; extern ITranslator *translator; +extern IGameConfig *g_pGameConf; #endif /* _INCLUDE_SOURCEMOD_LOGIC_BRIDGE_H_ */ diff --git a/core/sm_globals.h b/core/sm_globals.h index d4ba97ea..03e749cf 100644 --- a/core/sm_globals.h +++ b/core/sm_globals.h @@ -201,12 +201,10 @@ namespace SourceMod { class IThreader; class ITextParsers; - class IMemoryUtils; } extern IThreader *g_pThreader; extern ITextParsers *textparsers; -extern IMemoryUtils *memutils; #include "sm_autonatives.h" diff --git a/core/sm_stringutil.cpp b/core/sm_stringutil.cpp index 86664ddd..0d6b9d0a 100644 --- a/core/sm_stringutil.cpp +++ b/core/sm_stringutil.cpp @@ -1361,38 +1361,6 @@ char *UTIL_TrimWhitespace(char *str, size_t &len) return str; } -size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr) -{ - size_t written = 0; - size_t length = strlen(hexstr); - - for (size_t i = 0; i < length; i++) - { - if (written >= maxlength) - break; - buffer[written++] = hexstr[i]; - if (hexstr[i] == '\\' && hexstr[i + 1] == 'x') - { - if (i + 3 >= length) - continue; - /* Get the hex part. */ - char s_byte[3]; - int r_byte; - s_byte[0] = hexstr[i + 2]; - s_byte[1] = hexstr[i + 3]; - s_byte[2] = '\0'; - /* Read it as an integer */ - sscanf(s_byte, "%x", &r_byte); - /* Save the value */ - buffer[written - 1] = r_byte; - /* Adjust index */ - i += 3; - } - } - - return written; -} - char *UTIL_ToLowerCase(const char *str) { size_t len = strlen(str); diff --git a/core/sm_stringutil.h b/core/sm_stringutil.h index 781f1a73..494e2389 100644 --- a/core/sm_stringutil.h +++ b/core/sm_stringutil.h @@ -57,7 +57,6 @@ size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list ap); char *sm_strdup(const char *str); char *UTIL_TrimWhitespace(char *str, size_t &len); -size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr); char *UTIL_ToLowerCase(const char *str); #endif // _INCLUDE_SOURCEMOD_STRINGUTIL_H_ diff --git a/core/smn_entities.cpp b/core/smn_entities.cpp index 38e4746d..8a42240a 100644 --- a/core/smn_entities.cpp +++ b/core/smn_entities.cpp @@ -34,8 +34,9 @@ #include "sourcemm_api.h" #include "PlayerManager.h" #include "HalfLife2.h" -#include "GameConfigs.h" +#include #include "sm_stringutil.h" +#include "logic_bridge.h" enum PropType { diff --git a/core/smn_hudtext.cpp b/core/smn_hudtext.cpp index 32e759bd..ca1f34a2 100644 --- a/core/smn_hudtext.cpp +++ b/core/smn_hudtext.cpp @@ -30,11 +30,12 @@ */ #include "sm_globals.h" -#include "GameConfigs.h" +#include #include "UserMessages.h" #include "TimerSys.h" #include "PlayerManager.h" #include "HandleSys.h" +#include "logic_bridge.h" #define MAX_HUD_CHANNELS 6 diff --git a/core/sourcemod.cpp b/core/sourcemod.cpp index c5a74c26..229abfc6 100644 --- a/core/sourcemod.cpp +++ b/core/sourcemod.cpp @@ -44,7 +44,7 @@ #include "PlayerManager.h" #include "ForwardSys.h" #include "TimerSys.h" -#include "GameConfigs.h" +#include #include "DebugReporter.h" #include "frame_hooks.h" #include "logic_bridge.h" @@ -62,6 +62,7 @@ ISourcePawnEngine *g_pSourcePawn = NULL; ISourcePawnEngine2 *g_pSourcePawn2 = NULL; IdentityToken_t *g_pCoreIdent = NULL; IForward *g_pOnMapEnd = NULL; +IGameConfig *g_pGameConf = NULL; bool g_Loaded = false; bool sm_show_debug_spew = false; @@ -277,6 +278,7 @@ void SourceModBase::StartSourceMod(bool late) pBase->OnSourceModStartup(false); pBase = pBase->m_pGlobalClassNext; } + g_pGameConf = logicore.GetCoreGameConfig(); /* Notify! */ pBase = SMGlobalClass::head; diff --git a/public/IGameHelpers.h b/public/IGameHelpers.h index 87cced0e..a6510c44 100644 --- a/public/IGameHelpers.h +++ b/public/IGameHelpers.h @@ -40,7 +40,7 @@ */ #define SMINTERFACE_GAMEHELPERS_NAME "IGameHelpers" -#define SMINTERFACE_GAMEHELPERS_VERSION 5 +#define SMINTERFACE_GAMEHELPERS_VERSION 6 class CBaseEntity; class CBaseHandle; @@ -262,6 +262,14 @@ namespace SourceMod * @param msg The kick message to show to the player. */ virtual void AddDelayedKick(int client, int userid, const char *msg) =0; + + /** + * @brief Returns the uncomputed offset of a SendProp. + * + * @param prop SendProp pointer. + * @return Uncomputed sendprop offset. + */ + virtual int GetSendPropOffset(SendProp *prop) =0; }; }