Skip to content

Commit d096f18

Browse files
Autorefresh Module (#67)
* autorefresh: added autorefresh module * autorefresh: renaming both hooks * readme: updating readme regarding autorefresh * autorefresh: adding linux x64 signature * autorefresh: cleaned up code, added stability safeguards experimenting with readability thingies * readme: fixing inconsistency * autorefresh: fix formatting damn * autorefresh: small changes * autorefresh: removed table of strings input support - it doesn't seem to be useful * autorefresh: giving the PreLuaAutoRefresh Hook more weight * readme: fixing mistakes * autorefresh: cleaning up * gameserver: apply networking limit increases --------- Co-authored-by: Raphael <[email protected]>
1 parent d80691c commit d096f18

File tree

4 files changed

+177
-2
lines changed

4 files changed

+177
-2
lines changed

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ Wiki: https://holylib.raphaelit7.com/
214214
\- \- [CGameClient](https://github.com/RaphaelIT7/gmod-holylib#cgameclient)<br>
215215
\- \- [Singleplayer](https://github.com/RaphaelIT7/gmod-holylib#singleplayer)<br>
216216
\- \- [128+ Players](https://github.com/RaphaelIT7/gmod-holylib#128-players)<br>
217+
\- [autorefresh](#autorefresh)<br>
217218

218219
[Unfinished Modules](https://github.com/RaphaelIT7/gmod-holylib#unfinished-modules)<br>
219220
\- [serverplugins](https://github.com/RaphaelIT7/gmod-holylib#serverplugins)<br>
@@ -4554,6 +4555,46 @@ hook.Add("HolyLib:OnPlayerChangedSlot", "Example", function(oldPlayerSlot, newPl
45544555
end)
45554556
```
45564557

4558+
## autorefresh
4559+
The Autorefresh module currently provides functionalities regarding the in-built lua file autorefresh system.
4560+
4561+
Supports: Linux32 | LINUX64
4562+
4563+
### Functions
4564+
#### autorefresh.DenyLuaAutoRefresh(string filePath, bool shouldDeny)
4565+
Prevents certain Lua files from being autorefreshed. Accepts a string of the relative file path and a bool indicating whether to block or allow the autorefresh.
4566+
- `true` - denies the autorefresh
4567+
- `false` - allows the autorefresh
4568+
```lua
4569+
local pathToFile = "lua/test-dir/test.lua"
4570+
autorefresh.DenyLuaAutoRefresh(pathToFile, true)
4571+
```
4572+
4573+
### Hooks
4574+
#### bool HolyLib:PreLuaAutoRefresh(string filePath, string fileName)
4575+
Called before a Lua file is being refreshed. If `true` is returned it will deny the refresh of the lua file.
4576+
- string filePath — is the filePath provided relative to the garrysmod folder
4577+
- string filename — is the filename without the extension
4578+
```lua
4579+
hook.Add("HolyLib:PreLuaAutoRefresh", "ExamplePreAutoRefresh", function(filePath, fileName)
4580+
print("[BEFORE] FileChanged: " .. filePath .. filename)
4581+
4582+
if filename == "bogos" then
4583+
print("Denying Refresh")
4584+
return true -- prevent refresh
4585+
end
4586+
end)
4587+
```
4588+
4589+
#### HolyLib:PostLuaAutoRefresh(string filePath, string fileName)
4590+
Called after a Lua file is refreshed.
4591+
Note that if a refresh is being denied by PreLuaAutorefresh or DenyLuaAutoRefresh, this hook won't be called.
4592+
```lua
4593+
hook.Add("HolyLib:PostLuaAutoRefresh", "ExamplePostAutoRefresh", function(filePath, fileName)
4594+
print("[AFTER] FileChanged: " .. filePath .. filename)
4595+
end)
4596+
```
4597+
45574598
# Unfinished Modules
45584599

45594600
## serverplugins

source/modules/autorefresh.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#include "module.h"
2+
#include "LuaInterface.h"
3+
#include "lua.h"
4+
#include "detours.h"
5+
6+
#include <unordered_map>
7+
8+
#include "tier0/memdbgon.h"
9+
10+
class CAutoRefreshModule : public IModule
11+
{
12+
public:
13+
virtual void LuaInit(GarrysMod::Lua::ILuaInterface* pLua, bool bServerInit) OVERRIDE;
14+
virtual void LuaShutdown(GarrysMod::Lua::ILuaInterface* pLua) OVERRIDE;
15+
virtual void InitDetour(bool bPreServer) OVERRIDE;
16+
virtual const char* Name() { return "autorefresh"; };
17+
virtual int Compatibility() { return LINUX32 | LINUX64; };
18+
};
19+
20+
CAutoRefreshModule g_pAutoRefreshModule;
21+
IModule* pAutoRefreshModule = &g_pAutoRefreshModule;
22+
23+
static std::unordered_map<std::string, bool> blockedLuaFilesMap = {};
24+
LUA_FUNCTION_STATIC(DenyLuaAutoRefresh)
25+
{
26+
LUA->CheckType(1, GarrysMod::Lua::Type::String);
27+
LUA->CheckType(2, GarrysMod::Lua::Type::Bool);
28+
29+
const char* inputFilePath = LUA->GetString(1);
30+
bool blockStatus = LUA->GetBool(2);
31+
char normalizedPath[260];
32+
V_FixupPathName(normalizedPath, sizeof(normalizedPath), inputFilePath);
33+
blockedLuaFilesMap.insert_or_assign(std::string(normalizedPath), blockStatus);
34+
35+
return 0;
36+
}
37+
38+
static Detouring::Hook detour_CAutoRefresh_HandleChange_Lua;
39+
static bool hook_CAutoRefresh_HandleChange_Lua(const std::string* pfileRelPath, const std::string* pfileName, const std::string* pfileExt)
40+
{
41+
auto trampoline = detour_CAutoRefresh_HandleChange_Lua.GetTrampoline<Symbols::GarrysMod_AutoRefresh_HandleChange_Lua>();
42+
if (!g_Lua || !pfileRelPath || !pfileName || !pfileExt)
43+
{
44+
return trampoline(pfileRelPath, pfileName, pfileExt);
45+
}
46+
47+
if (std::string(pfileExt->substr(0, 3)) != "lua")
48+
{
49+
return trampoline(pfileRelPath, pfileName, pfileExt);
50+
}
51+
52+
bool bDenyRefresh = false;
53+
if (Lua::PushHook("HolyLib:PreLuaAutoRefresh"))
54+
{
55+
g_Lua->PushString(pfileRelPath->c_str());
56+
g_Lua->PushString(pfileName->c_str());
57+
58+
if (g_Lua->CallFunctionProtected(3, 1, true))
59+
{
60+
bDenyRefresh = g_Lua->GetBool(-1);
61+
g_Lua->Pop(1);
62+
}
63+
}
64+
65+
if (!blockedLuaFilesMap.empty() && !bDenyRefresh)
66+
{
67+
char fullPath[260];
68+
V_ComposeFileName(pfileRelPath->c_str(), pfileName->c_str(), fullPath, sizeof(fullPath));
69+
V_SetExtension(fullPath, "lua", sizeof(fullPath));
70+
if (auto fileSearch = blockedLuaFilesMap.find(fullPath); fileSearch != blockedLuaFilesMap.end())
71+
{
72+
bDenyRefresh = fileSearch->second;
73+
}
74+
}
75+
76+
if (bDenyRefresh)
77+
{
78+
return true;
79+
}
80+
81+
bool originalResult = trampoline(pfileRelPath, pfileName, pfileExt);
82+
83+
if (Lua::PushHook("HolyLib:PostLuaAutoRefresh"))
84+
{
85+
g_Lua->PushString(pfileRelPath->c_str());
86+
g_Lua->PushString(pfileName->c_str());
87+
88+
g_Lua->CallFunctionProtected(3, 0, true);
89+
}
90+
91+
return originalResult;
92+
};
93+
94+
void CAutoRefreshModule::LuaInit(GarrysMod::Lua::ILuaInterface* pLua, bool bServerInit)
95+
{
96+
if (bServerInit)
97+
return;
98+
99+
Util::StartTable(pLua);
100+
Util::AddFunc(pLua, DenyLuaAutoRefresh, "DenyLuaAutoRefresh");
101+
Util::FinishTable(pLua, "autorefresh");
102+
}
103+
104+
void CAutoRefreshModule::LuaShutdown(GarrysMod::Lua::ILuaInterface* pLua)
105+
{
106+
Util::NukeTable(pLua, "autorefresh");
107+
}
108+
109+
void CAutoRefreshModule::InitDetour(bool bPreServer)
110+
{
111+
if (bPreServer)
112+
return;
113+
114+
SourceSDK::FactoryLoader server_loader("server");
115+
Detour::Create(
116+
&detour_CAutoRefresh_HandleChange_Lua, "CAutoRefresh_HandleChange_Lua",
117+
server_loader.GetModule(), Symbols::GarrysMod_AutoRefresh_HandleChange_LuaSym,
118+
(void*)hook_CAutoRefresh_HandleChange_Lua, m_pID
119+
);
120+
}

source/symbols.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,8 +894,16 @@ namespace Symbols
894894
const std::vector<Symbol> s_NetChannelsSym = {
895895
Symbol::FromName("_ZL13s_NetChannels"),
896896
};
897-
898-
const std::vector<Symbol> NET_SetTimeSym = {
897+
898+
const std::vector<Symbol> NET_SetTimeSym = {
899899
Symbol::FromName("_Z11NET_SetTimed"),
900900
};
901+
902+
//---------------------------------------------------------------------------------
903+
// Purpose: AutoRefresh Symbols
904+
//---------------------------------------------------------------------------------
905+
const std::vector<Symbol> GarrysMod_AutoRefresh_HandleChange_LuaSym = {
906+
Symbol::FromName("_ZN9GarrysMod11AutoRefresh16HandleChange_LuaERKSsS2_S2_"),
907+
Symbol::FromSignature("\x55\x48\x89\xE5\x41\x57\x41\x56\x49\x89\xD6\x41\x55\x49\x89\xFD\x48\x89\xD7\x41\x54"),
908+
};
901909
}

source/symbols.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,4 +658,10 @@ namespace Symbols
658658

659659
typedef ConCommandBase* (*CCvar_FindCommandBase)(ICvar*, const char* name);
660660
extern const std::vector<Symbol> CCvar_FindCommandBaseSym;
661+
662+
//---------------------------------------------------------------------------------
663+
// Purpose: AutoRefresh Symbols
664+
//---------------------------------------------------------------------------------
665+
typedef bool (*GarrysMod_AutoRefresh_HandleChange_Lua)(const std::string* fileRelPath, const std::string* fileName, const std::string* fileExt);
666+
extern const std::vector<Symbol> GarrysMod_AutoRefresh_HandleChange_LuaSym;
661667
}

0 commit comments

Comments
 (0)