diff --git a/cssdk/public/interface.cpp b/cssdk/public/interface.cpp index 9a12eef..ccc703c 100644 --- a/cssdk/public/interface.cpp +++ b/cssdk/public/interface.cpp @@ -64,7 +64,7 @@ EXPORT_FUNCTION IBaseInterface *CreateInterface( const char *pName, int *pReturn return pCur->m_CreateFn(); } } - + if ( pReturnCode ) { *pReturnCode = IFACE_FAILED; @@ -76,7 +76,7 @@ EXPORT_FUNCTION IBaseInterface *CreateInterface( const char *pName, int *pReturn static IBaseInterface *CreateInterfaceLocal( const char *pName, int *pReturnCode ) { InterfaceReg *pCur; - + for(pCur=InterfaceReg::s_pInterfaceRegs; pCur; pCur=pCur->m_pNext) { if(strcmp(pCur->m_pName, pName) == 0) @@ -88,12 +88,12 @@ static IBaseInterface *CreateInterfaceLocal( const char *pName, int *pReturnCode return pCur->m_CreateFn(); } } - + if ( pReturnCode ) { *pReturnCode = IFACE_FAILED; } - return NULL; + return NULL; } #endif @@ -107,7 +107,7 @@ static IBaseInterface *CreateInterfaceLocal( const char *pName, int *pReturnCode // Input : pModuleName - module name // *pName - proc name //----------------------------------------------------------------------------- -//static hlds_run wants to use this function +//static hlds_run wants to use this function void *Sys_GetProcAddress( const char *pModuleName, const char *pName ) { return GetProcAddress( GetModuleHandle(pModuleName), pName ); @@ -118,7 +118,7 @@ void *Sys_GetProcAddress( const char *pModuleName, const char *pName ) // Input : pModuleName - module name // *pName - proc name //----------------------------------------------------------------------------- -// hlds_run wants to use this function +// hlds_run wants to use this function void *Sys_GetProcAddress( void *pModuleHandle, const char *pName ) { #if defined ( _WIN32 ) @@ -128,6 +128,14 @@ void *Sys_GetProcAddress( void *pModuleHandle, const char *pName ) #endif } +// Purpose: Returns a module handle by its name. +// Input : pModuleName - module name +// Output : the module handle or NULL in case of an error +CSysModule *Sys_GetModuleHandle(const char *pModuleName) +{ + return reinterpret_cast(GetModuleHandle(pModuleName)); +} + //----------------------------------------------------------------------------- // Purpose: Loads a DLL/component from disk and returns a handle to it // Input : *pModuleName - filename of the component @@ -170,7 +178,7 @@ CSysModule *Sys_LoadModule( const char *pModuleName ) #elif defined(OSX) printf("Error:%s\n",dlerror()); _snprintf( str, sizeof(str), "%s.dylib", szAbsoluteModuleName ); - hDLL = dlopen(str, RTLD_NOW); + hDLL = dlopen(str, RTLD_NOW); #else printf("Error:%s\n",dlerror()); _snprintf( str, sizeof(str), "%s.so", szAbsoluteModuleName ); @@ -202,7 +210,7 @@ void Sys_UnloadModule( CSysModule *pModule ) //----------------------------------------------------------------------------- // Purpose: returns a pointer to a function, given a module -// Input : module - windows HMODULE from Sys_LoadModule() +// Input : module - windows HMODULE from Sys_LoadModule() // *pName - proc name // Output : factory for this module //----------------------------------------------------------------------------- @@ -216,9 +224,9 @@ CreateInterfaceFn Sys_GetFactory( CSysModule *pModule ) return reinterpret_cast(GetProcAddress( hDLL, CREATEINTERFACE_PROCNAME )); #else // Linux gives this error: -//../public/interface.cpp: In function `IBaseInterface *(*Sys_GetFactory +//../public/interface.cpp: In function `IBaseInterface *(*Sys_GetFactory //(CSysModule *)) (const char *, int *)': -//../public/interface.cpp:154: ISO C++ forbids casting between +//../public/interface.cpp:154: ISO C++ forbids casting between //pointer-to-function and pointer-to-object // // so lets get around it :) @@ -252,9 +260,9 @@ CreateInterfaceFn Sys_GetFactory( const char *pModuleName ) return static_cast( Sys_GetProcAddress( pModuleName, CREATEINTERFACE_PROCNAME ) ); #else // Linux gives this error: -//../public/interface.cpp: In function `IBaseInterface *(*Sys_GetFactory +//../public/interface.cpp: In function `IBaseInterface *(*Sys_GetFactory //(const char *)) (const char *, int *)': -//../public/interface.cpp:186: invalid static_cast from type `void *' to +//../public/interface.cpp:186: invalid static_cast from type `void *' to //type `IBaseInterface *(*) (const char *, int *)' // // so lets use the old style cast. diff --git a/cssdk/public/interface.h b/cssdk/public/interface.h index 3349146..bacc75c 100644 --- a/cssdk/public/interface.h +++ b/cssdk/public/interface.h @@ -8,10 +8,10 @@ // Versioning // There are two versioning cases that are handled by this: -// 1. You add functions to the end of an interface, so it is binary compatible with the previous interface. In this case, +// 1. You add functions to the end of an interface, so it is binary compatible with the previous interface. In this case, // you need two EXPOSE_INTERFACEs: one to expose your class as the old interface and one to expose it as the new interface. -// 2. You update an interface so it's not compatible anymore (but you still want to be able to expose the old interface -// for legacy code). In this case, you need to make a new version name for your new interface, and make a wrapper interface and +// 2. You update an interface so it's not compatible anymore (but you still want to be able to expose the old interface +// for legacy code). In this case, you need to make a new version name for your new interface, and make a wrapper interface and // expose it for the old interface. //#if _MSC_VER >= 1300 // VC7 @@ -108,7 +108,7 @@ public: // This function is automatically exported and allows you to access any interfaces exposed with the above macros. // if pReturnCode is set, it will return one of the following values // extend this for other error conditions/code -enum +enum { IFACE_OK = 0, IFACE_FAILED @@ -133,6 +133,8 @@ extern CreateInterfaceFn Sys_GetFactory( const char *pModuleName ); // load/unload components class CSysModule; +extern CSysModule *Sys_GetModuleHandle(const char *pModuleName); + //----------------------------------------------------------------------------- // Load & Unload should be called in exactly one place for each module // The factory for that module should be passed on to dependent components for diff --git a/include/engine_rehlds_api.h b/include/engine_rehlds_api.h index 3fd6780..1b7cea6 100644 --- a/include/engine_rehlds_api.h +++ b/include/engine_rehlds_api.h @@ -3,8 +3,11 @@ #pragma once -extern IRehldsApi* g_RehldsApi; -extern IRehldsHookchains* g_RehldsHookchains; +extern IRehldsApi *g_RehldsApi; +extern const RehldsFuncs_t *g_RehldsFuncs; +extern IRehldsServerData *g_RehldsData; +extern IRehldsHookchains *g_RehldsHookchains; +extern IRehldsServerStatic *g_RehldsSvs; extern bool RehldsApi_Init(); typedef struct packet_entities_s { diff --git a/src/engine_rehlds_api.cpp b/src/engine_rehlds_api.cpp index fa231a8..9a6a82b 100644 --- a/src/engine_rehlds_api.cpp +++ b/src/engine_rehlds_api.cpp @@ -1,48 +1,63 @@ #include "precompiled.h" -IRehldsApi* g_RehldsApi; -IRehldsHookchains* g_RehldsHookchains; +IRehldsApi *g_RehldsApi; +const RehldsFuncs_t *g_RehldsFuncs; +IRehldsServerData *g_RehldsData; +IRehldsHookchains *g_RehldsHookchains; +IRehldsServerStatic *g_RehldsSvs; -bool RehldsApi_TryInit(CSysModule* engineModule, char* failureReason) +bool RehldsApi_Init() { - if (!engineModule) { - SEM_PRINT("[%s]: ReHLDS Failed to locate engine module.", Plugin_info.logtag); - return false; +#ifdef WIN32 + // Find the most appropriate module handle from a list of DLL candidates + // Notes: + // - "swds.dll" is the library Dedicated Server + // + // Let's also attempt to locate the ReHLDS API in the client's library + // - "sw.dll" is the client library for Software render, with a built-in listenserver + // - "hw.dll" is the client library for Hardware render, with a built-in listenserver + const char *dllNames[] = { "swds.dll", "sw.dll", "hw.dll" }; // List of DLL candidates to lookup for the ReHLDS API + CSysModule *engineModule = NULL; // The module handle of the selected DLL + for (const char *dllName : dllNames) + { + if (engineModule = Sys_GetModuleHandle(dllName)) + break; // gotcha } +#else + CSysModule *engineModule = Sys_GetModuleHandle("engine_i486.so"); +#endif + + if (!engineModule) + return false; + CreateInterfaceFn ifaceFactory = Sys_GetFactory(engineModule); - - if (!ifaceFactory) { - SEM_PRINT("[%s]: ReHLDS Failed to locate interface factory in engine module.", Plugin_info.logtag); + if (!ifaceFactory) return false; - } int retCode = 0; - g_RehldsApi = (IRehldsApi*)ifaceFactory(VREHLDS_HLDS_API_VERSION, &retCode); - if (!g_RehldsApi) { - SEM_PRINT("[%s]: ReHLDS Failed to locate retrieve rehlds api interface from engine module, return code is %d.", Plugin_info.logtag, retCode); + if (!g_RehldsApi) return false; - } int majorVersion = g_RehldsApi->GetMajorVersion(); int minorVersion = g_RehldsApi->GetMinorVersion(); if (majorVersion != REHLDS_API_VERSION_MAJOR) { - SEM_PRINT("[%s]: ReHLDS API major version mismatch; expected %d, real %d.", Plugin_info.logtag, REHLDS_API_VERSION_MAJOR, majorVersion); + SEM_PRINT("[%s]: ReHLDS API major version mismatch; expected %d, real %d\n", Plugin_info.logtag, REHLDS_API_VERSION_MAJOR, majorVersion); // need to notify that it is necessary to update the ReHLDS. if (majorVersion < REHLDS_API_VERSION_MAJOR) { - SEM_PRINT("[%s]: Please update the ReHLDS up to a major version API >= %d.", Plugin_info.logtag, REHLDS_API_VERSION_MAJOR); + SEM_PRINT("[%s]: Please update the ReHLDS up to a major version API >= %d\n", Plugin_info.logtag, REHLDS_API_VERSION_MAJOR); } // need to notify that it is necessary to update the module. else if (majorVersion > REHLDS_API_VERSION_MAJOR) { - SEM_PRINT("[%s]: Please update the %s up to a major version API >= %d.", Plugin_info.logtag, Plugin_info.name, majorVersion); + SEM_PRINT("[%s]: Please update the %s up to a major version API >= %d\n", Plugin_info.logtag, Plugin_info.logtag, majorVersion); } return false; @@ -50,39 +65,15 @@ bool RehldsApi_TryInit(CSysModule* engineModule, char* failureReason) if (minorVersion < REHLDS_API_VERSION_MINOR) { - SEM_PRINT("[%s]: ReHLDS API minor version mismatch; expected at least %d, real %d.", Plugin_info.logtag, REHLDS_API_VERSION_MINOR, minorVersion); - SEM_PRINT("[%s]: Please update the ReHLDS up to a minor version API >= %d.", Plugin_info.logtag, REHLDS_API_VERSION_MINOR); + SEM_PRINT("[%s]: ReHLDS API minor version mismatch; expected at least %d, real %d\n", Plugin_info.logtag, REHLDS_API_VERSION_MINOR, minorVersion); + SEM_PRINT("[%s]: Please update the ReHLDS up to a minor version API >= %d\n", Plugin_info.logtag, REHLDS_API_VERSION_MINOR); return false; } + g_RehldsFuncs = g_RehldsApi->GetFuncs(); + g_RehldsData = g_RehldsApi->GetServerData(); g_RehldsHookchains = g_RehldsApi->GetHookchains(); - - return true; -} - -bool RehldsApi_Init() -{ - char failReason[2048]; - -#ifdef WIN32 - CSysModule* engineModule = Sys_LoadModule("swds.dll"); - if (!RehldsApi_TryInit(engineModule, failReason)) - { - engineModule = Sys_LoadModule("filesystem_stdio.dll"); - if (!RehldsApi_TryInit(engineModule, failReason)) - { - UTIL_LogPrintf("%s", failReason); - return false; - } - } -#else - CSysModule* engineModule = Sys_LoadModule("engine_i486.so"); - if (!RehldsApi_TryInit(engineModule, failReason)) - { - UTIL_LogPrintf("%s", failReason); - return false; - } -#endif + g_RehldsSvs = g_RehldsApi->GetServerStatic(); return true; }