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
This commit is contained in:
David Anderson 2010-05-14 23:35:42 -07:00
parent 96f6cdf677
commit 64455b9852
25 changed files with 254 additions and 204 deletions

View File

@ -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',

View File

@ -44,7 +44,7 @@
#include "Logger.h"
#include "compat_wrappers.h"
#include "ConsoleDetours.h"
#include "GameConfigs.h"
#include <IGameConfigs.h>
#include "sm_stringutil.h"
#include "ConCmdManager.h"
#include "HalfLife2.h"

View File

@ -35,9 +35,10 @@
#include "UserMessages.h"
#include "PlayerManager.h"
#include "sm_stringutil.h"
#include "GameConfigs.h"
#include <IGameConfigs.h>
#include <compat_wrappers.h>
#include <Logger.h>
#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();
}

View File

@ -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();

View File

@ -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

View File

@ -32,11 +32,12 @@
#include "MenuStyle_Radio.h"
#include "sm_stringutil.h"
#include "UserMessages.h"
#include "GameConfigs.h"
#include <IGameConfigs.h>
#include "PlayerManager.h"
#if defined MENU_DEBUG
#include "Logger.h"
#endif
#include "logic_bridge.h"
extern const char *g_RadioNumTable[];
CRadioStyle g_RadioMenuStyle;

View File

@ -44,7 +44,7 @@
#include "HalfLife2.h"
#include <inetchannel.h>
#include <iclient.h>
#include "GameConfigs.h"
#include <IGameConfigs.h>
#include "ExtensionSys.h"
#include <sourcemod_version.h>
#include "ConsoleDetours.h"

View File

@ -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':

View File

@ -27,24 +27,28 @@
* or <http://www.sourcemod.net/license.php>.
*/
#include "common_logic.h"
#include <string.h>
#include <stdlib.h>
#include <sh_list.h>
#include <sh_string.h>
#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 <IGameHelpers.h>
#include <ILibrarySys.h>
#include <IHandleSys.h>
#include <IMemoryUtils.h>
#include "logic_bridge.h"
#include <ISourceMod.h>
#include "common_logic.h"
#include "sm_crc32.h"
#include "MemoryUtils.h"
#if defined PLATFORM_LINUX
#include <dlfcn.h>
#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<AddressConf>();
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
if (smcore.SymbolsAreHidden())
final_addr = g_MemUtils.ResolveSymbol(handle, &s_TempSig.sig[1]);
else
final_addr = dlsym(handle, &s_TempSig.sig[1]);
#endif
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<String>::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)
{

View File

@ -32,13 +32,12 @@
#ifndef _INCLUDE_SOURCEMOD_CGAMECONFIGS_H_
#define _INCLUDE_SOURCEMOD_CGAMECONFIGS_H_
#include "common_logic.h"
#include <IGameConfigs.h>
#include <ITextParsers.h>
#include <sh_list.h>
#include "sm_trie.h"
#include "sm_globals.h"
#include "sm_memtable.h"
#include "sm_trie_tpl.h"
#include <sm_trie_tpl.h>
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<int> m_Offsets;
KTrie<SendProp *> m_Props;
KTrie<int> m_Keys;
KTrie<void *> m_Sigs;
unsigned int m_RefCount;
/* Parse states */
int m_ParseState;
@ -137,7 +136,7 @@ public: //SMGlobalClass
void OnSourceModAllShutdown();
private:
List<CGameConfig *> m_cfgs;
Trie *m_pLookup;
KTrie<CGameConfig *> m_Lookup;
public:
KTrie<ITextListener_SMC *> m_customHandlers;
};

View File

@ -38,6 +38,8 @@ OBJECTS = \
smn_string.cpp \
smn_handles.cpp \
smn_datapacks.cpp \
smn_gameconfigs.cpp \
GameConfigs.cpp \
smn_players.cpp
##############################################

View File

@ -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()

View File

@ -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);

View File

@ -29,24 +29,24 @@
* Version: $Id$
*/
#include "sourcemod.h"
#include "HandleSys.h"
#include "common_logic.h"
#include <IHandleSys.h>
#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);

View File

@ -30,6 +30,7 @@
*/
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <sm_platform.h>
#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;
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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"

View File

@ -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);

View File

@ -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_

View File

@ -34,8 +34,9 @@
#include "sourcemm_api.h"
#include "PlayerManager.h"
#include "HalfLife2.h"
#include "GameConfigs.h"
#include <IGameConfigs.h>
#include "sm_stringutil.h"
#include "logic_bridge.h"
enum PropType
{

View File

@ -30,11 +30,12 @@
*/
#include "sm_globals.h"
#include "GameConfigs.h"
#include <IGameConfigs.h>
#include "UserMessages.h"
#include "TimerSys.h"
#include "PlayerManager.h"
#include "HandleSys.h"
#include "logic_bridge.h"
#define MAX_HUD_CHANNELS 6

View File

@ -44,7 +44,7 @@
#include "PlayerManager.h"
#include "ForwardSys.h"
#include "TimerSys.h"
#include "GameConfigs.h"
#include <IGameConfigs.h>
#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;

View File

@ -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;
};
}