4
4
#include " filesystem.hpp"
5
5
#include " utils.hpp"
6
6
#include " core.hpp"
7
+ #include " config.hpp"
7
8
8
9
#include < tier0/dbg.h>
9
10
#include < chrono>
14
15
#include < scanning/symbolfinder.hpp>
15
16
#include < detouring/hook.hpp>
16
17
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
-
27
18
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);
29
20
30
21
std::vector<Symbol> HandleFileChange = {
31
22
#if ARCHITECTURE_IS_X86
32
23
#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 " ),
34
25
#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 " ),
36
27
#endif
37
28
#elif ARCHITECTURE_IS_X86_64
38
29
#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 " ),
40
31
#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 " )
42
33
#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 " ),
44
35
#endif
45
36
#endif
46
37
};
47
38
48
39
static SymbolFinder finder;
49
40
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;
52
53
}
53
54
54
55
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) {
57
57
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 ;
61
61
}
62
- return ptr ;
62
+ return {} ;
63
63
}
64
64
}
65
65
@@ -86,14 +86,22 @@ void WatchdogListener::handleFileAction(efsw::WatchID watchid, const std::string
86
86
Watchdog::Watchdog (std::shared_ptr<Core> core, std::shared_ptr<Filesystem> fs)
87
87
: core(core), fs(fs)
88
88
{
89
+ m_HandleFileChangeHook = std::make_unique<Detouring::Hook>();
89
90
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" );
93
91
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\t Please, 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\t Please, 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\t Please, report to " MOONLOADER_URL " /issues\n " );
104
+ }
97
105
}
98
106
99
107
void Watchdog::Start () {
@@ -103,7 +111,6 @@ void Watchdog::Start() {
103
111
104
112
Watchdog::~Watchdog () {
105
113
m_HandleFileChangeHook->Disable ();
106
- m_HandleFileChangeHook->Destroy ();
107
114
}
108
115
109
116
void Watchdog::OnFileModified (const std::string& path) {
@@ -189,5 +196,9 @@ void Watchdog::HandleFileChange(const std::string& path) {
189
196
}
190
197
191
198
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
+ }
193
204
}
0 commit comments