diff --git a/src/filesystem_find.cpp b/src/filesystem_find.cpp index 10d7289..c831e24 100644 --- a/src/filesystem_find.cpp +++ b/src/filesystem_find.cpp @@ -6,7 +6,7 @@ static bool IsOK(const char *name) { OpenResult opener(name); - return opener.GetResult(); + return opener.GetResult().shouldOpen; } static const char *NextFile(FileFindHandle_t pHandle) { diff --git a/src/filesystem_open.cpp b/src/filesystem_open.cpp index ce08662..07252e9 100644 --- a/src/filesystem_open.cpp +++ b/src/filesystem_open.cpp @@ -14,14 +14,22 @@ FileHandle_t VirtualFunctionHooks::IBaseFileSystem__Open(const char *pFileName, g_pFullFileSystem->RelativePathToFullPath(pFileName, pathID, temp, sizeof(temp) - 1); char relative_path[4096]; relative_path[4095] = 0; + IOpenResult res; + if (g_pFullFileSystem->FullPathToRelativePathEx(temp, "BASE_PATH", relative_path, sizeof relative_path - 1)) { OpenResult opener(relative_path); - if (!opener.GetResult()) { + res = opener.GetResult(); + if (!res.shouldOpen) { return 0; } } - return FunctionHooks->BaseFileSystemReplacer->Call(FunctionHooks->IBaseFileSystem__Open__index, pFileName, pOptions, pathID); + if (res.shouldRedirect) { + return FunctionHooks->BaseFileSystemReplacer->Call(FunctionHooks->IBaseFileSystem__Open__index, res.redirect.c_str(), pOptions, res.redirectPathID.c_str()); + } + else { + return FunctionHooks->BaseFileSystemReplacer->Call(FunctionHooks->IBaseFileSystem__Open__index, pFileName, pOptions, pathID); + } } @@ -30,7 +38,7 @@ int ThinkHook(lua_State *state) { OpenResult::m.lock(); for (int i = v.size() - 1; i >= 0; i--) { OpenResult *res = v[i]; - res->result = res->RunLua(); + res->RunLua(); v.erase(v.begin() + i); res->has_result = true; } diff --git a/src/openresult.h b/src/openresult.h index e0286a6..c9bbdff 100644 --- a/src/openresult.h +++ b/src/openresult.h @@ -3,42 +3,72 @@ #include #include +#include #include "threadtools.h" #include "GarrysMod/Lua/Interface.h" #include "vfuncs.h" +struct IOpenResult { + bool shouldOpen; + bool shouldRedirect; + std::string redirect; + std::string redirectPathID; +}; + class OpenResult { public: OpenResult(const char *relativetobase) { file = relativetobase; } - bool GetResult() { + IOpenResult GetResult() { if (ThreadGetCurrentId() == FunctionHooks->mainthread) { - return RunLua(); + RunLua(); } - OpenResult::m.lock(); - this->has_result = false; - OpenResult::waiting_list.push_back(this); - OpenResult::m.unlock(); + else { + OpenResult::m.lock(); + this->has_result = false; + OpenResult::waiting_list.push_back(this); + OpenResult::m.unlock(); - while (!this->has_result) - ThreadSleep(2); + while (!this->has_result) + ThreadSleep(2); + } return this->result; } - bool RunLua() { + void RunLua() { auto lua = FunctionHooks->lua; lua->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB); lua->GetField(-1, "hook"); lua->GetField(-1, "Run"); lua->PushString("ShouldHideFile"); lua->PushString(file); - lua->Call(2, 1); - bool ret = !lua->GetBool(-1); - lua->Pop(3); - return ret; + lua->Call(2, 2); + + if (lua->IsType(-2,GarrysMod::Lua::Type::BOOL)) { + this->result.shouldOpen = !lua->GetBool(-2); + this->result.shouldRedirect = false; + } + else if (lua->IsType(-2,GarrysMod::Lua::Type::STRING)) { + this->result.shouldOpen = true; + this->result.shouldRedirect = true; + this->result.redirect = std::string(lua->GetString(-2)); + + if (lua->IsType(-1, GarrysMod::Lua::Type::STRING)) { + this->result.redirectPathID = std::string(lua->GetString(-1)); + } + else { + this->result.redirectPathID = "BASE_PATH"; + } + } + else { + this->result.shouldOpen = true; + this->result.shouldRedirect = false; + } + + lua->Pop(4); } public: @@ -46,6 +76,6 @@ class OpenResult { static std::vector waiting_list; const char *file; bool has_result; - bool result; + IOpenResult result; }; #endif // OPENRESULT_H \ No newline at end of file