Skip to content

Commit 49b5439

Browse files
authored
Merge pull request #24 from Pika-Software/dev
Update `HandleFileChange` signatures
2 parents 7971780 + 9739541 commit 49b5439

12 files changed

+101
-97
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.vscode
22
/build*
3-
.DS_Store
3+
.DS_Store
4+
CMakeUserPresets.json

CMakeLists.txt

+36-37
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
cmake_minimum_required(VERSION 3.22)
2-
enable_language(CXX C)
3-
4-
# Require C++ 17
5-
set(CMAKE_CXX_STANDARD 17)
6-
set(CMAKE_CXX_STANDARD_REQUIRED ON)
7-
8-
# Enable -fPIC flag
9-
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
102

113
# Enable IDE folders
124
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
@@ -21,34 +13,8 @@ if(APPLE)
2113
)
2214
endif()
2315

24-
# Debug build is unsupported on MSVC
25-
if(MSVC)
26-
list(REMOVE_ITEM CMAKE_CONFIGURATION_TYPES "Debug")
27-
endif()
28-
29-
# Force old ABI for Linux, since Garry's Mod ABI is used
30-
if(UNIX AND NOT APPLE)
31-
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
32-
endif()
33-
34-
# Include extensions
35-
add_subdirectory(cmake)
36-
37-
# Entropia File System Watcher
38-
add_subdirectory(third-party/efsw)
39-
40-
# Include embedded lua
41-
# add_subdirectory(third-party/lua)
42-
add_subdirectory(third-party/lpeg)
43-
44-
# Add moonengine library
45-
add_subdirectory(moonengine)
46-
47-
# Include garrysmod_common
48-
find_garrysmod_common()
49-
if(NOT GARRYSMOD_COMMON_FOUND) # Check if garrysmod_common has been found
50-
message(FATAL_ERROR "garrysmod_common not found")
51-
endif()
16+
# Allow CMake find custom package finders
17+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
5218

5319
# Get the latest abbreviated commit hash of the working branch
5420
execute_process(
@@ -71,8 +37,41 @@ endif()
7137
file(STRINGS "VERSION" GM_MOONLOADER_VERSION)
7238
project(gm_moonloader
7339
VERSION ${GM_MOONLOADER_VERSION}
74-
LANGUAGES CXX
40+
LANGUAGES CXX C
7541
HOMEPAGE_URL "https://github.com/Pika-Software/gm_moonloader"
7642
)
7743

44+
# Require C++ 17
45+
set(CMAKE_CXX_STANDARD 17)
46+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
47+
48+
# Enable -fPIC flag
49+
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
50+
51+
# Debug build is unsupported on MSVC
52+
if(MSVC)
53+
list(REMOVE_ITEM CMAKE_CONFIGURATION_TYPES "Debug")
54+
endif()
55+
56+
# Force old ABI for Linux, since Garry's Mod ABI is used
57+
if(UNIX AND NOT APPLE)
58+
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
59+
endif()
60+
61+
# Include extensions
62+
add_subdirectory(cmake)
63+
64+
# Entropia File System Watcher
65+
add_subdirectory(third-party/efsw)
66+
67+
# Include embedded lua
68+
# add_subdirectory(third-party/lua)
69+
add_subdirectory(third-party/lpeg)
70+
71+
# Add moonengine library
72+
add_subdirectory(moonengine)
73+
74+
# Include garrysmod_common
75+
find_package(GarrysmodCommon REQUIRED)
76+
7877
add_subdirectory(source)

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.1.7
1+
2.1.8

cmake/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
include(find_garrysmod_common.cmake)
21
include(CMakeRC.cmake)
32
include(find_Yuescript.cmake)
43
include(find_lua52.cmake)

cmake/FindGarrysmodCommon.cmake

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
message(STATUS "Looking for garrysmod_common...")
2+
set(GARRYSMOD_COMMON_PATH "GARRYSMOD_COMMON_NOT_FOUND" CACHE PATH "Path to garrysmod_common (https://github.com/dankmolot/garrysmod_common/tree/master-cmake)")
3+
cmake_path(ABSOLUTE_PATH GARRYSMOD_COMMON_PATH NORMALIZE)
4+
5+
if(NOT IS_DIRECTORY ${GARRYSMOD_COMMON_PATH} OR NOT EXISTS ${GARRYSMOD_COMMON_PATH}/CMakeLists.txt OR ${GARRYSMOD_COMMON_PATH} STREQUAL ${CMAKE_CURRENT_LIST_DIR})
6+
message(FATAL_ERROR "Invalid path to garrysmod_common. Please set valid GARRYSMOD_COMMON_PATH")
7+
endif()
8+
9+
add_subdirectory(${GARRYSMOD_COMMON_PATH} ${CMAKE_BINARY_DIR}/garrysmod_common)
10+
set(GarrysmodCommon_FOUND TRUE)

cmake/find_garrysmod_common.cmake

-11
This file was deleted.

source/global.hpp

-5
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@
77
#include <Platform.hpp>
88

99
#if IS_SERVERSIDE
10-
#if ARCHITECTURE_IS_X86
11-
#include <Color.h>
12-
#else
1310
#include <color.h>
14-
#endif
15-
1611
#include <unordered_set>
1712
#else
1813
struct Color {

source/main.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ GMOD_MODULE_OPEN() {
2020
core->Deinitialize();
2121
core.reset();
2222

23-
ILUA->ThrowError(Utils::Format("error during moonloader core initialization: %s", e.what()).c_str());
23+
ILUA->ThrowError(Utils::Format("[Moonloader] Fatal error: %s", e.what()).c_str());
2424
}
2525

2626
return 0;
@@ -39,4 +39,4 @@ GMOD_MODULE_CLOSE() {
3939
}
4040

4141
return 0;
42-
}
42+
}

source/watchdog.cpp

+43-32
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "filesystem.hpp"
55
#include "utils.hpp"
66
#include "core.hpp"
7+
#include "config.hpp"
78

89
#include <tier0/dbg.h>
910
#include <chrono>
@@ -14,52 +15,51 @@
1415
#include <scanning/symbolfinder.hpp>
1516
#include <detouring/hook.hpp>
1617

17-
#if SYSTEM_IS_WINDOWS
18-
#if ARCHITECTURE_IS_X86
19-
#define GMCOMMON_CALLING_CONVENTION __stdcall
20-
#else
21-
#define GMCOMMON_CALLING_CONVENTION __fastcall
22-
#endif
23-
#else
24-
#define GMCOMMON_CALLING_CONVENTION
25-
#endif
26-
2718
namespace Symbols {
28-
typedef void (GMCOMMON_CALLING_CONVENTION *HandleFileChange_t)(const std::string& path);
19+
typedef void (GMCOMMON_CALLING_CONVENTION_STD *HandleFileChange_t)(const std::string& path);
2920

3021
std::vector<Symbol> HandleFileChange = {
3122
#if ARCHITECTURE_IS_X86
3223
#if SYSTEM_IS_WINDOWS
33-
Symbol::FromSignature("\x55\x8b\xec\x83\xec\x60\x56\x8b\x75\x08\x8d\x45\xd0\x57\x56\x50\xe8\x2A\x2A\x2A\x00\x83\xc4\x08\x83\x7d\xe0\x00\x0f\x84\x60\x02"),
24+
Symbol::FromSignature("\x55\x8b\xec\x83\xec\x60\x56\x8b\x75\x08\x8d\x45\xd0\x56\x50\xe8\x2A\x2A\x2A\x2A\x83\xc4\x08\x83\x7d\xe0\x00\x0f\x84"),
3425
#elif SYSTEM_IS_LINUX
35-
Symbol::FromSignature("\x55\x89\xe5\x57\x56\x53\x8d\x5d\x98\x83\xec\x7c\x8b\x75\x08\x89\x1c\x24\x89\x74\x24\x04\xe8\x2A\x2A\x2A\x00\x8b\x45\x98\x83\xec"),
26+
Symbol::FromSignature("\x55\x89\xe5\x57\x56\x53\x8d\x5d\x98\x83\xec\x7c\x8b\x75\x08\x89\x1c\x24\x89\x74\x24\x04\xe8\x2A\x2A\x2A\x2A\x8b\x45\x98\x83\xec\x04\x8b\x50\xf4\x85\xd2\x0f\x84"),
3627
#endif
3728
#elif ARCHITECTURE_IS_X86_64
3829
#if SYSTEM_IS_WINDOWS
39-
Symbol::FromSignature("\x48\x89\x5c\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7c\x24\x20\x55\x48\x8d\x6c\x24\xa9\x48\x81\xec\xb0\x00\x00\x00\x48\x8b\x05\x2A"),
30+
Symbol::FromSignature("\x48\x89\x5c\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7c\x24\x20\x55\x48\x8d\x6c\x24\xa9\x48\x81\xec\xb0\x00\x00\x00\x48\x8b\x05\x2A\x2A\x2A\x2A\x48\x33\xc4\x48\x89\x45\x47\x48\x8b\xf9\x48\x8b\xd1\x48\x8d\x4d\xc7\xe8\x2A\x2A\x2A\x2A\x48\x83\x7d\xd7\x00\x0f\x84"),
4031
#elif SYSTEM_IS_LINUX
41-
Symbol::FromSignature("\x55\x48\x89\xfe\x48\x89\xe5\x41\x57\x41\x56\x41\x55\x41\x54\x4c\x8d\x65\x80\x53\x48\x89\xfb\x4c\x89\xe7\x48\x83\xec\x68\xe8\x2A")
32+
Symbol::FromSignature("\x55\x48\x89\xfe\x48\x89\xe5\x41\x57\x41\x56\x41\x55\x41\x54\x4c\x8d\x65\x80\x53\x48\x89\xfb\x4c\x89\xe7\x48\x83\xec\x68\xe8\x2A\x2A\x2A\x2A\x48\x8b\x45\x80\x48\x83\x78\xe8\x00\x75")
4233
#elif SYSTEM_IS_MACOSX
43-
Symbol::FromSignature("\x55\x48\x89\xe5\x53\x48\x81\xec\x88\x00\x00\x00\x48\x89\xfb\x48\x8d\x7d\xc8\x48\x89\xde\xe8\x2A\x2A\x2A\x00\x8a\x4d\xc8\x89\xc8"),
34+
Symbol::FromSignature("\x55\x48\x89\xe5\x53\x48\x81\xec\x88\x00\x00\x00\x48\x89\xfb\x48\x8d\x7d\xc8\x48\x89\xde\xe8\x2A\x2A\x2A\x2A\x8a\x4d\xc8\x89\xc8\x24\x01\x74"),
4435
#endif
4536
#endif
4637
};
4738

4839
static SymbolFinder finder;
4940
template<typename T>
50-
static inline T ResolveSymbol(SourceSDK::FactoryLoader& loader, const Symbol& symbol) {
51-
return reinterpret_cast<T>( finder.Resolve(loader.GetModule(), symbol.name.c_str(), symbol.length) );
41+
static inline std::vector<T> ResolveSymbol(SourceSDK::FactoryLoader& loader, const Symbol& symbol) {
42+
static_assert(std::is_pointer<T>::value, "T must be a pointer");
43+
44+
// vector used to catch if signature eventually find more than one function
45+
// I'm still new into signatures, so they may be wrong
46+
std::vector<T> pointers;
47+
void* ptr = nullptr;
48+
while (ptr = finder.Resolve(loader.GetModule(), symbol.name.c_str(), symbol.length, ptr)) {
49+
pointers.push_back( reinterpret_cast<T>(ptr) );
50+
ptr = reinterpret_cast<void*>(reinterpret_cast<char*>(ptr) + 1);
51+
}
52+
return pointers;
5253
}
5354

5455
template<typename T>
55-
static inline T ResolveSymbols(SourceSDK::FactoryLoader& loader, const std::vector<Symbol>& symbols) {
56-
T ptr = nullptr;
56+
static inline std::vector<T> ResolveSymbols(SourceSDK::FactoryLoader& loader, const std::vector<Symbol>& symbols) {
5757
for (const auto& symbol : symbols) {
58-
ptr = ResolveSymbol<T>(loader, symbol);
59-
if (ptr != nullptr)
60-
break;
58+
auto pointers = ResolveSymbol<T>(loader, symbol);
59+
if (!pointers.empty())
60+
return pointers;
6161
}
62-
return ptr;
62+
return {};
6363
}
6464
}
6565

@@ -86,14 +86,22 @@ void WatchdogListener::handleFileAction(efsw::WatchID watchid, const std::string
8686
Watchdog::Watchdog(std::shared_ptr<Core> core, std::shared_ptr<Filesystem> fs)
8787
: core(core), fs(fs)
8888
{
89+
m_HandleFileChangeHook = std::make_unique<Detouring::Hook>();
8990
SourceSDK::FactoryLoader server_loader("server");
90-
auto HandleFileChange_original = Symbols::ResolveSymbols<Symbols::HandleFileChange_t>(server_loader, Symbols::HandleFileChange);
91-
if (HandleFileChange_original == nullptr)
92-
throw std::runtime_error("Failed to resolve HandleFileChange");
9391

94-
m_HandleFileChangeHook = std::make_unique<Detouring::Hook>((void*)HandleFileChange_original, (void*)HandleFileChange_detour);
95-
if (!m_HandleFileChangeHook->Enable())
96-
throw std::runtime_error("Failed to hook HandleFileChange");
92+
auto HandleFileChange_pointers = Symbols::ResolveSymbols<Symbols::HandleFileChange_t>(server_loader, Symbols::HandleFileChange);
93+
if (HandleFileChange_pointers.size() == 1) {
94+
auto HandleFileChange_original = HandleFileChange_pointers[0];
95+
if (m_HandleFileChangeHook->Create((void*)HandleFileChange_original, (void*)HandleFileChange_detour) && m_HandleFileChangeHook->Enable()) {
96+
DevMsg("[Moonloader] HandleFileChange: %p\n", HandleFileChange_original);
97+
} else {
98+
core->LUA->ErrorNoHalt("[Moonloader] Failed to hook HandleFileChange function! Autorefresh won't work properly.\n\tPlease, report to " MOONLOADER_URL "/issues\n");
99+
}
100+
} else if (HandleFileChange_pointers.empty()) {
101+
core->LUA->ErrorNoHalt("[Moonloader] HandleFileChange not found! Autorefresh won't work properly.\n\tPlease, report to " MOONLOADER_URL "/issues\n" );
102+
} else {
103+
core->LUA->ErrorNoHalt("[Moonloader] Too many functions were found for HandleFileChange signature! Autorefresh won't work properly.\n\tPlease, report to " MOONLOADER_URL "/issues\n");
104+
}
97105
}
98106

99107
void Watchdog::Start() {
@@ -103,7 +111,6 @@ void Watchdog::Start() {
103111

104112
Watchdog::~Watchdog() {
105113
m_HandleFileChangeHook->Disable();
106-
m_HandleFileChangeHook->Destroy();
107114
}
108115

109116
void Watchdog::OnFileModified(const std::string& path) {
@@ -189,5 +196,9 @@ void Watchdog::HandleFileChange(const std::string& path) {
189196
}
190197

191198
void Watchdog::RefreshFile(const std::string& path) {
192-
m_HandleFileChangeHook->GetTrampoline<Symbols::HandleFileChange_t>()(path);
199+
if (m_HandleFileChangeHook->IsValid()) {
200+
m_HandleFileChangeHook->GetTrampoline<Symbols::HandleFileChange_t>()(path);
201+
} else {
202+
// TODO: use lua_refresh_file?
203+
}
193204
}

source/watchdog.hpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88
#include <unordered_set>
99
#include <queue>
1010
#include <mutex>
11-
#include <tier0/platform.h>
1211
#include <efsw/efsw.hpp>
1312
#include <GarrysMod/Lua/LuaInterface.h>
14-
15-
namespace Detouring {
16-
class Hook;
17-
}
13+
#include <detouring/hook.hpp>
1814

1915
namespace GarrysMod::Lua {
2016
class File;
2117
}
2218

19+
namespace Detouring {
20+
class Hook;
21+
}
22+
2323
namespace MoonLoader {
2424
class Watchdog;
2525
class Filesystem;

third-party/Yuescript

0 commit comments

Comments
 (0)