diff --git a/source/CScriptEngine.cpp b/source/CScriptEngine.cpp index 640de6fb..6e5cd61a 100644 --- a/source/CScriptEngine.cpp +++ b/source/CScriptEngine.cpp @@ -983,27 +983,33 @@ namespace CLEO } // [game root]\cleo - std::string scriptsDir = CFileMgr::ms_rootDirName; + /*std::string scriptsDir = CFileMgr::ms_rootDirName; if (!scriptsDir.empty() && scriptsDir.back() != '\\') scriptsDir.push_back('\\'); - scriptsDir += "cleo"; + scriptsDir += "cleo";*/ + std::string scriptsDir = "cleo"; // TODO: restore to absolute path when ModLoader is updated to support CLEO5 TRACE("Searching for cleo scripts"); - FilesWalk(scriptsDir.c_str(), cs_ext, [this](const char* fullPath, const char* filename) { - auto cs = LoadScript(fullPath); - cs->SetDebugMode(NativeScriptsDebugMode); // inherit from global state + CCustomScript* cs = nullptr; + FilesWalk(scriptsDir.c_str(), cs_ext, [&](const char* fullPath, const char* filename) { + cs = LoadScript(fullPath); }); - FilesWalk(scriptsDir.c_str(), cs4_ext, [this](const char* fullPath, const char* filename) { - auto cs = LoadScript(fullPath); + FilesWalk(scriptsDir.c_str(), cs4_ext, [&](const char* fullPath, const char* filename) { + cs = LoadScript(fullPath); if (cs) cs->SetCompatibility(CLEO_VER_4); }); - FilesWalk(scriptsDir.c_str(), cs3_ext, [this](const char* fullPath, const char* filename) { - auto cs = LoadScript(fullPath); + FilesWalk(scriptsDir.c_str(), cs3_ext, [&](const char* fullPath, const char* filename) { + cs = LoadScript(fullPath); if (cs) cs->SetCompatibility(CLEO_VER_3); }); + if (cs != nullptr) + { + cs->SetDebugMode(NativeScriptsDebugMode); // inherit from global state + } + for (void* func : GetInstance().GetCallbacks(eCallbackId::ScriptsLoaded)) { typedef void WINAPI callback(void); diff --git a/source/FileEnumerator.h b/source/FileEnumerator.h index de43c605..03d442b7 100644 --- a/source/FileEnumerator.h +++ b/source/FileEnumerator.h @@ -4,7 +4,7 @@ template void FilesWalk(const char* directory, const char* extension, T callback) { - try + /*try { for (auto& it : std::filesystem::directory_iterator(directory)) { @@ -28,5 +28,39 @@ void FilesWalk(const char* directory, const char* extension, T callback) catch (const std::exception& ex) { TRACE("Error while iterating directory: %s", ex.what()); + }*/ + + // Re-implemented with raw search APIs for compatibility with ModLoader. + // The ModLoader should be updated anyway to solve potential file access problems in more advanced Cleo scripts + + std::string pattern = directory; + if(!pattern.empty() && pattern.back() != '\\') pattern.push_back('\\'); + + std::string_view baseDir = pattern; + + pattern.push_back('*'); + if (extension != nullptr) pattern.append(extension); + + WIN32_FIND_DATA wfd = { 0 }; + HANDLE hSearch = FindFirstFile(pattern.c_str(), &wfd); + + if (hSearch == INVALID_HANDLE_VALUE) + { + TRACE("No files found in: %s", pattern.c_str()); + return; } + do + { + if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + continue; // skip directories + } + + //auto result = std::filesystem::absolute(std::string(baseDir) + wfd.cFileName); + auto result = std::filesystem::path(std::string(baseDir) + wfd.cFileName); // ModLoader supports only relative paths... + callback(result.string().c_str(), result.filename().string().c_str()); + + } while (FindNextFile(hSearch, &wfd)); + + FindClose(hSearch); }