This repository has been archived by the owner on Jul 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 168
/
Copy pathextension.h
157 lines (124 loc) · 4.39 KB
/
extension.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#pragma once
#include "modengine/extension_logger.h"
#include "modengine/hook.h"
#include "modengine/game_type.h"
#include "settings.h"
#include <memory>
#include <string>
#include <functional>
#include <sol/sol.hpp>
#include <spdlog/spdlog.h>
namespace modengine {
class ModEngine;
class ModEngineExtensionConnectorV1 {
public:
ModEngineExtensionConnectorV1(ModEngine* mod_engine)
: m_mod_engine(mod_engine)
{
}
private:
ModEngine* m_mod_engine;
public:
virtual int connector_version()
{
return 1;
}
virtual void register_hook(GameType type, Hook<GenericFunctionPointer>* hook);
virtual void register_hook(GameType type, ScannedHook<GenericFunctionPointer>* hook);
virtual void install_hooks();
virtual void register_patch(GameType type, const std::string_view& signature, std::function<void(uintptr_t)> replace_callback);
virtual void register_patch(GameType type, uint64_t addr, std::function<void(uintptr_t)> replace_callback);
virtual ConfigReader create_config_reader(const char** names, size_t names_len);
virtual ExtensionLogger* logger();
virtual lua_State* lua();
};
using ModEngineExtensionConnector = ModEngineExtensionConnectorV1;
class ModEngineExtension {
public:
ModEngineExtension(ModEngineExtensionConnector* connector)
: m_ext_connector(connector)
{
#ifdef MODENGINE_EXTERNAL
auto sink = std::make_shared<detail::ExtensionLoggerSink>(connector->logger());
auto logger = std::make_shared<spdlog::logger>("modengine", sink);
spdlog::set_default_logger(logger);
#endif
}
ModEngineExtension(const ModEngineExtension&) = delete;
virtual ~ModEngineExtension()
{
}
virtual void on_attach() = 0;
virtual void on_detach() = 0;
virtual const char* id() = 0;
protected:
void reapply()
{
m_ext_connector->install_hooks();
}
template <typename T>
void register_hook(GameType type, Hook<T> *hook, const std::wstring& module, const std::string& function, T detour)
{
auto mod = GetModuleHandleW(module.c_str());
if (mod == nullptr) {
return;
}
auto addr = (uintptr_t)GetProcAddress(mod, function.c_str());
if (addr == 0) {
return;
}
hook->original = (T)addr;
hook->replacement = detour;
m_ext_connector->register_hook(type, (Hook<GenericFunctionPointer>*)hook);
}
template <typename T>
// TODO: ABI compatibility, std::shared_ptr
void register_hook(GameType type, Hook<T> *hook, uintptr_t location, T detour)
{
hook->original = reinterpret_cast<T>(location);
hook->replacement = detour;
m_ext_connector->register_hook(type, (Hook<GenericFunctionPointer>*) hook);
}
template <typename T>
void register_hook(GameType type, Hook<T> *hook)
{
m_ext_connector->register_hook(type, (Hook<GenericFunctionPointer>*)hook);
}
template <typename T>
void register_hook(GameType type, ScannedHook<T> *hook, const ScanPattern &signature, int64_t offset, T detour, HookScanMode mode)
{
hook->mode = mode;
hook->pattern = signature;
hook->offset = offset;
hook->replacement = detour;
m_ext_connector->register_hook(type, (ScannedHook<GenericFunctionPointer>*) hook);
}
template <typename T>
void register_hook(GameType type, ScannedHook<T> *hook)
{
m_ext_connector->register_hook(type, (ScannedHook<GenericFunctionPointer>*)hook);
}
// TODO: ABI compatibility, std::string_view, std::function
inline void register_patch(GameType type, const std::string_view& signature, std::function<void(uintptr_t)> replace_callback)
{
m_ext_connector->register_patch(type, signature, replace_callback);
}
template <ConfigObject T>
T get_config()
{
std::vector<const char*> paths { "extension", id() };
return m_ext_connector->create_config_reader(paths.data(), paths.size()).read_config_object<T>({});
};
// TODO: ABI compatibility, std::function
inline void register_patch(GameType type, uint64_t addr, std::function<void(uintptr_t)> replace_callback)
{
m_ext_connector->register_patch(type, addr, replace_callback);
}
inline sol::state_view lua()
{
return sol::state_view(m_ext_connector->lua());
}
private:
ModEngineExtensionConnector* m_ext_connector;
};
}