diff --git a/BunnymodXT/helper_functions.cpp b/BunnymodXT/helper_functions.cpp new file mode 100644 index 00000000..2f7676d0 --- /dev/null +++ b/BunnymodXT/helper_functions.cpp @@ -0,0 +1,51 @@ +#include "stdafx.hpp" +#include "modules.hpp" + +namespace helper_functions +{ + void com_fixslashes(std::string &str) + { + // https://github.com/ValveSoftware/halflife/blob/c7240b965743a53a29491dd49320c88eecf6257b/game_shared/bot/nav_file.cpp#L680 + #ifdef _WIN32 + str = std::regex_replace(str, std::regex("/"), "\\"); + #else + str = std::regex_replace(str, std::regex("\\"), "/"); + #endif + } + + std::string add_os_library_extension(std::string str) + { + #ifdef _WIN32 + std::string extension = ".dll"; + #else + std::string extension = ".so"; + #endif + + return str += extension; + } + + const char *swap_lib(const char* current_lib_path, std::string new_lib_path, const char *start) + { + com_fixslashes(new_lib_path); + + const std::string filename = current_lib_path; + const auto index = filename.find(start); + static std::string new_path; + new_path = filename.substr(0, index) + add_os_library_extension(new_lib_path).c_str(); + + return new_path.c_str(); + } + + void crash_if_failed(std::string str) + { + EngineWarning("%s", str.c_str()); + + #ifdef _WIN32 + MessageBox(NULL, str.c_str(), "Fatal Error", MB_OK | MB_ICONERROR); + #endif + + ClientDLL::GetInstance().pEngfuncs = nullptr; + ServerDLL::GetInstance().pEngfuncs = nullptr; + HwDLL::GetInstance().ppGlobals = nullptr; + } +}; \ No newline at end of file diff --git a/BunnymodXT/helper_functions.hpp b/BunnymodXT/helper_functions.hpp new file mode 100644 index 00000000..a6f12a9d --- /dev/null +++ b/BunnymodXT/helper_functions.hpp @@ -0,0 +1,9 @@ +#pragma once + +namespace helper_functions +{ + void com_fixslashes(std::string &str); + std::string add_os_library_extension(std::string str); + const char *swap_lib(const char* current_lib_path, std::string new_lib_path, const char *start); + void crash_if_failed(std::string str); +} \ No newline at end of file diff --git a/BunnymodXT/modules/HwDLL.cpp b/BunnymodXT/modules/HwDLL.cpp index b762ff55..99c40e12 100644 --- a/BunnymodXT/modules/HwDLL.cpp +++ b/BunnymodXT/modules/HwDLL.cpp @@ -23,6 +23,7 @@ #include "../custom_triggers.hpp" #include "../simulation_ipc.hpp" #include "../splits.hpp" +#include "../helper_functions.hpp" using namespace std::literals; @@ -348,9 +349,9 @@ extern "C" qboolean __cdecl CL_ReadDemoMessage_OLD() return HwDLL::HOOKED_CL_ReadDemoMessage_OLD(); } -extern "C" void __cdecl LoadThisDll(char *szDllFilename) +extern "C" void __cdecl LoadThisDll(const char *szDllFilename) { - return HwDLL::HOOKED_LoadThisDll_Linux(szDllFilename); + return HwDLL::HOOKED_LoadThisDll(szDllFilename); } #endif @@ -743,7 +744,6 @@ void HwDLL::Clear() ORIG_ValidStuffText = nullptr; ORIG_CL_ReadDemoMessage_OLD = nullptr; ORIG_LoadThisDll = nullptr; - ORIG_LoadThisDll_Linux = nullptr; ClientDLL::GetInstance().pEngfuncs = nullptr; ServerDLL::GetInstance().pEngfuncs = nullptr; @@ -1334,10 +1334,10 @@ void HwDLL::FindStuff() else EngineDevWarning("[hw dll] Could not find g_sv_delta.\n"); - ORIG_LoadThisDll_Linux = reinterpret_cast<_LoadThisDll_Linux>(MemUtils::GetSymbolAddress(m_Handle, "LoadThisDll")); - if (ORIG_LoadThisDll_Linux) - EngineDevMsg("[hw dll] Found LoadThisDll at %p.\n", ORIG_LoadThisDll_Linux); - else { + ORIG_LoadThisDll = reinterpret_cast<_LoadThisDll>(MemUtils::GetSymbolAddress(m_Handle, "LoadThisDll")); + if (ORIG_LoadThisDll) { + EngineDevMsg("[hw dll] Found LoadThisDll at %p.\n", ORIG_LoadThisDll); + } else { EngineDevWarning("[hw dll] Could not find LoadThisDll.\n"); EngineWarning("[hw dll] AmxModX might crash with BunnymodXT.\n"); } @@ -8072,68 +8072,33 @@ HOOK_DEF_0(HwDLL, qboolean, __cdecl, CL_ReadDemoMessage_OLD) return rv; } -void SwapMetamodDll(char* current_dll_path, const char* new_dll_path) { - const std::string filename = std::string(current_dll_path); - const auto addons_index = filename.find("addons"); - auto new_path = filename.substr(0, addons_index) + new_dll_path; - - strcpy(current_dll_path, new_path.c_str()); -} - -HOOK_DEF_1(HwDLL, void, __fastcall, LoadThisDll, char*, szDllFilename) +HOOK_DEF_1(HwDLL, void, __cdecl, LoadThisDll, const char*, szDllFilename) { - // error: ‘const std::string’ {aka ‘const class std::__cxx11::basic_string’} has no member named ‘ends_with’ - // :smiley: - if (boost::ends_with(szDllFilename, "metamod.dll")) { - auto &cl = ClientDLL::GetInstance(); - static bool is_cstrike = cl.DoesGameDirMatch("cstrike"); - + if (boost::ends_with(szDllFilename, helper_functions::add_os_library_extension("metamod").c_str())) + { EngineDevMsg("[hw dll] AmxModX detected.\n"); - if (is_cstrike) { - static const char *cs_windows = "dlls/mp.dll"; - - SwapMetamodDll(szDllFilename, cs_windows); - EngineDevMsg("[hw dll] Current mod is cstrike. AmxModX is disabled.\n"); - } else { - EngineWarning("[hw dll] Cannot disable AmdModX for current mod. Edit /liblist.gam to continue.\n"); + static bool is_cstrike = ClientDLL::GetInstance().DoesGameDirMatch("cstrike"); + if (is_cstrike) + { + #ifdef _WIN32 + const std::string cs_lib = "dlls\\mp"; + #else + const std::string cs_lib = "dlls/cs"; + #endif - if (ORIG_Host_Shutdown) - ORIG_Host_Shutdown(); - else - exit(-1); + EngineDevMsg("[hw dll] Old path to game library: %s\n", szDllFilename); + szDllFilename = helper_functions::swap_lib(szDllFilename, cs_lib, "addons"); + EngineDevMsg("[hw dll] New path to game library: %s\n", szDllFilename); + EngineDevMsg("[hw dll] AmxModX is disabled.\n"); } - - } - - ORIG_LoadThisDll(szDllFilename); -} - -HOOK_DEF_1(HwDLL, void, __cdecl, LoadThisDll_Linux, char*, szDllFilename) -{ - // error: ‘const std::string’ {aka ‘const class std::__cxx11::basic_string’} has no member named ‘ends_with’ - // :smiley: - if (boost::ends_with(szDllFilename, "metamod.so")) { - auto &cl = ClientDLL::GetInstance(); - static bool is_cstrike = cl.DoesGameDirMatch("cstrike"); - - EngineDevMsg("[hw dll] AmxModX detected.\n"); - - if (is_cstrike) { - static const char *cs_linux = "dlls/cs.so"; - - SwapMetamodDll(szDllFilename, cs_linux); - EngineDevMsg("[hw dll] Current mod is cstrike. AmxModX is disabled.\n"); - } else { - EngineWarning("[hw dll] Cannot disable AmdModX for current mod. Edit /liblist.gam to continue.\n"); - - if (ORIG_Host_Shutdown) - ORIG_Host_Shutdown(); - else - exit(-1); + else + { + const std::string error_msg = "[hw dll] Cannot disable AmdModX for current mod. Edit /liblist.gam to continue.\n"; + helper_functions::crash_if_failed(error_msg); } } - ORIG_LoadThisDll_Linux(szDllFilename); + ORIG_LoadThisDll(szDllFilename); } diff --git a/BunnymodXT/modules/HwDLL.hpp b/BunnymodXT/modules/HwDLL.hpp index 90513750..b54e7332 100644 --- a/BunnymodXT/modules/HwDLL.hpp +++ b/BunnymodXT/modules/HwDLL.hpp @@ -86,8 +86,7 @@ class HwDLL : public IHookableNameFilterOrdered HOOK_DECL(void, __cdecl, ReleaseEntityDlls) HOOK_DECL(qboolean, __cdecl, ValidStuffText, char* buf) HOOK_DECL(qboolean, __cdecl, CL_ReadDemoMessage_OLD) - HOOK_DECL(void, __fastcall, LoadThisDll, char* szDllFilename) - HOOK_DECL(void, __cdecl, LoadThisDll_Linux, char* szDllFilename) + HOOK_DECL(void, __cdecl, LoadThisDll, const char* szDllFilename) struct cmdbuf_t { diff --git a/BunnymodXT/stdafx.hpp b/BunnymodXT/stdafx.hpp index f03a2891..2c720acb 100644 --- a/BunnymodXT/stdafx.hpp +++ b/BunnymodXT/stdafx.hpp @@ -46,6 +46,7 @@ typedef unsigned long long steamid_t; #include #include #include +#include using std::uintptr_t; using std::size_t; diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d762245..ae131e00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,6 +180,7 @@ set (HEADER_FILES BunnymodXT/input_editor.hpp BunnymodXT/simulation_ipc.hpp BunnymodXT/splits.hpp + BunnymodXT/helper_functions.hpp BunnymodXT/git_revision.hpp) set (SOURCE_FILES @@ -206,6 +207,7 @@ set (SOURCE_FILES BunnymodXT/input_editor.cpp BunnymodXT/simulation_ipc.cpp BunnymodXT/splits.cpp + BunnymodXT/helper_functions.cpp ${CMAKE_CURRENT_BINARY_DIR}/BunnymodXT/git_revision.cpp) if (MSVC)