diff --git a/core/HalfLife2.cpp b/core/HalfLife2.cpp index 664a888f..32a4cf7b 100644 --- a/core/HalfLife2.cpp +++ b/core/HalfLife2.cpp @@ -38,8 +38,20 @@ #include #include #include +#include "LibrarySys.h" #include "logic_bridge.h" +#if defined _WIN32 +#define TIER0_NAME "tier0.dll" +#define VSTDLIB_NAME "vstdlib.dll" +#elif defined __APPLE__ +#define TIER0_NAME "libtier0.dylib" +#define VSTDLIB_NAME "libvstdlib.dylib" +#elif defined __linux__ +#define TIER0_NAME LIB_PREFIX "tier0" LIB_SUFFIX +#define VSTDLIB_NAME LIB_PREFIX "vstdlib" LIB_SUFFIX +#endif + CHalfLife2 g_HL2; ConVar *sv_lan = NULL; @@ -131,6 +143,12 @@ void CHalfLife2::OnSourceModAllInitialized() } void CHalfLife2::OnSourceModAllInitialized_Post() +{ + InitLogicalEntData(); + InitCommandLine(); +} + +void CHalfLife2::InitLogicalEntData() { char *addr = NULL; @@ -196,6 +214,64 @@ void CHalfLife2::OnSourceModAllInitialized_Post() } } +void CHalfLife2::InitCommandLine() +{ + char path[PLATFORM_MAX_PATH]; + char error[256]; + + g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "../bin/" TIER0_NAME); + + if (!g_LibSys.IsPathFile(path)) + { + g_Logger.LogError("Could not find path for: " TIER0_NAME); + return; + } + + ILibrary *lib = g_LibSys.OpenLibrary(path, error, sizeof(error)); + m_pGetCommandLine = (GetCommandLine)lib->GetSymbolAddress("CommandLine_Tier0"); + + /* '_Tier0' dropped on Alien Swarm version */ + if (m_pGetCommandLine == NULL) + { + m_pGetCommandLine = (GetCommandLine)lib->GetSymbolAddress("CommandLine"); + } + + if (m_pGetCommandLine == NULL) + { + /* We probably have a Ship engine. */ + lib->CloseLibrary(); + g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "../bin/" VSTDLIB_NAME); + if (!g_LibSys.IsPathFile(path)) + { + g_Logger.LogError("Could not find path for: " VSTDLIB_NAME); + return; + } + + if ((lib = g_LibSys.OpenLibrary(path, error, sizeof(error))) == NULL) + { + g_Logger.LogError("Could not load %s: %s", path, error); + return; + } + + m_pGetCommandLine = (GetCommandLine)lib->GetSymbolAddress("CommandLine"); + + if (m_pGetCommandLine == NULL) + { + g_Logger.LogError("Could not locate any command line functionality"); + } + + lib->CloseLibrary(); + } +} + +ICommandLine *CHalfLife2::GetValveCommandLine() +{ + if (!m_pGetCommandLine) + return NULL; + + return m_pGetCommandLine(); +} + #if !defined METAMOD_PLAPI_VERSION || PLAPI_VERSION < 11 bool CHalfLife2::IsOriginalEngine() { diff --git a/core/HalfLife2.h b/core/HalfLife2.h index bf8f876f..46dea7c6 100644 --- a/core/HalfLife2.h +++ b/core/HalfLife2.h @@ -44,6 +44,11 @@ #include #include #include +#include + +#undef GetCommandLine + +typedef ICommandLine *(*GetCommandLine)(); class CCommand; @@ -136,6 +141,7 @@ public: //IGameHelpers cell_t EntityToBCompatRef(CBaseEntity *pEntity); void *GetGlobalEntityList(); int GetSendPropOffset(SendProp *prop); + ICommandLine *GetValveCommandLine(); public: void AddToFakeCliCmdQueue(int client, int userid, const char *cmd); void ProcessFakeCliCmdQueue(); @@ -151,6 +157,9 @@ public: #endif private: DataTableInfo *_FindServerClass(const char *classname); +private: + void InitLogicalEntData(); + void InitCommandLine(); private: Trie *m_pClasses; List m_Tables; @@ -163,6 +172,7 @@ private: CStack m_FreeCmds; CStack m_CommandStack; Queue m_DelayedKicks; + GetCommandLine m_pGetCommandLine; }; extern CHalfLife2 g_HL2; diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index 6ee162fd..22baf093 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -44,7 +44,6 @@ #include "HalfLife2.h" #include #include -#include #include #include "ExtensionSys.h" #include @@ -244,7 +243,8 @@ void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int cl // clientMax will not necessarily be correct here (such as on late SourceTV enable) m_maxClients = gpGlobals->maxClients; - m_bIsSourceTVActive = (tv_enable && tv_enable->GetBool() && CommandLine()->FindParm("-nohltv") == 0); + ICommandLine *commandLine = g_HL2.GetValveCommandLine(); + m_bIsSourceTVActive = (tv_enable && tv_enable->GetBool() && (!commandLine || commandLine->FindParm("-nohltv") == 0)); m_bIsReplayActive = false; #if SOURCE_ENGINE == SE_ORANGEBOXVALVE m_bIsReplayActive = (replay_enable && replay_enable->GetBool()); diff --git a/public/IGameHelpers.h b/public/IGameHelpers.h index d9691062..08f817f4 100644 --- a/public/IGameHelpers.h +++ b/public/IGameHelpers.h @@ -40,12 +40,13 @@ */ #define SMINTERFACE_GAMEHELPERS_NAME "IGameHelpers" -#define SMINTERFACE_GAMEHELPERS_VERSION 7 +#define SMINTERFACE_GAMEHELPERS_VERSION 8 class CBaseEntity; class CBaseHandle; class SendProp; class ServerClass; +class ICommandLine; struct edict_t; struct datamap_t; struct typedescription_t; @@ -284,6 +285,13 @@ namespace SourceMod * @return True on success, false on failure. */ virtual bool HintTextMsg(int client, const char *msg) =0; + + /** + * @brief Retrieves the Valve command line pointer. + * + * @return ICommandLine ptr or NULL if not found. + */ + virtual ICommandLine *GetValveCommandLine() =0; }; }