diff --git a/cleo_sdk/CLEO_Utils.h b/cleo_sdk/CLEO_Utils.h index 9e20b316..bf88ce52 100644 --- a/cleo_sdk/CLEO_Utils.h +++ b/cleo_sdk/CLEO_Utils.h @@ -245,6 +245,30 @@ namespace CLEO return (void*)original; } + template + static StringList CreateStringList(const T& container) + { + StringList result; + result.count = 0; + result.strings = nullptr; + + if (container.size() > 0) + { + result.strings = (char**)malloc(container.size() * sizeof(DWORD)); // array of pointers + for (const std::string& s : container) + { + auto size = s.length() + 1; // and terminator character + auto str = (char*)malloc(size); + memcpy(str, s.c_str(), size); + + result.strings[result.count] = str; + result.count++; + } + } + + return result; + } + #define TRACE(format,...) {CLEO::Trace(CLEO::eLogLevel::Default, format, __VA_ARGS__);} #define LOG_WARNING(script, format, ...) {CLEO::Trace(script, CLEO::eLogLevel::Error, format, __VA_ARGS__);} #define SHOW_ERROR(a,...) {CLEO::ShowError(a, __VA_ARGS__);} diff --git a/source/CPluginSystem.cpp b/source/CPluginSystem.cpp index fb69e735..97b1af09 100644 --- a/source/CPluginSystem.cpp +++ b/source/CPluginSystem.cpp @@ -15,7 +15,8 @@ void CPluginSystem::LoadPlugins() if (pluginsLoaded) return; // already done std::set names; - std::vector filenames; + std::vector paths; + std::set skippedPaths; // load plugins from main CLEO directory auto ScanPluginsDir = [&](std::string path, const std::string prefix, const std::string extension) @@ -25,9 +26,12 @@ void CPluginSystem::LoadPlugins() for (DWORD i = 0; i < files.count; i++) { - if (std::find(filenames.begin(), filenames.end(), files.strings[i]) != filenames.end()) + if (std::find(paths.begin(), paths.end(), files.strings[i]) != paths.end()) continue; // file already listed + if (skippedPaths.find(files.strings[i]) != skippedPaths.end()) + continue; // file already skipped + auto name = FS::path(files.strings[i]).filename().string(); name = name.substr(prefix.length()); // cut off prefix name.resize(name.length() - extension.length()); // cut off extension @@ -40,11 +44,12 @@ void CPluginSystem::LoadPlugins() if (found == names.end()) { names.insert(name); - filenames.emplace_back(files.strings[i]); + paths.emplace_back(files.strings[i]); TRACE(" - '%s'", files.strings[i]); } else { + skippedPaths.emplace(files.strings[i]); LOG_WARNING(0, " - '%s' skipped, duplicate of `%s` plugin", files.strings[i], name.c_str()); } } @@ -58,9 +63,9 @@ void CPluginSystem::LoadPlugins() ScanPluginsDir(Filepath_Cleo, "", ".cleo"); // legacy plugins in old location // reverse order, so opcodes from CLEO5 plugins can overwrite opcodes from legacy plugins - if (!filenames.empty()) + if (!paths.empty()) { - for (auto it = filenames.crbegin(); it != filenames.crend(); it++) + for (auto it = paths.crbegin(); it != paths.crend(); it++) { const auto filename = it->c_str(); TRACE("Loading plugin '%s'", filename); diff --git a/source/CleoBase.cpp b/source/CleoBase.cpp index 09b5b423..48f6957e 100644 --- a/source/CleoBase.cpp +++ b/source/CleoBase.cpp @@ -256,19 +256,11 @@ namespace CLEO StringList WINAPI CLEO_ListDirectory(CLEO::CRunningScript* thread, const char* searchPath, BOOL listDirs, BOOL listFiles) { - StringList result; - result.count = 0; - result.strings = nullptr; - if (searchPath == nullptr) - { - return result; // invalid param - } + return {}; // invalid param if (!listDirs && !listFiles) - { - return result; // nothing to list, done - } + return {}; // nothing to list, done auto fsSearchPath = FS::path(searchPath); if (!fsSearchPath.is_absolute()) @@ -281,24 +273,18 @@ namespace CLEO } WIN32_FIND_DATA wfd = { 0 }; - HANDLE hSearch = FindFirstFile(searchPath, &wfd); + HANDLE hSearch = FindFirstFile(fsSearchPath.string().c_str(), &wfd); if (hSearch == INVALID_HANDLE_VALUE) - { - return result; - } + return {}; // nothing found std::set found; do { - if (!listDirs && (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { + if (!listDirs && (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) continue; // skip directories - } if (!listFiles && !(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { continue; // skip files - } auto path = FS::path(wfd.cFileName); if (!path.is_absolute()) // keep absolute in case somebody hooked the APIs to return so @@ -307,19 +293,9 @@ namespace CLEO found.insert(path.string()); } while (FindNextFile(hSearch, &wfd)); - // create results list - result.strings = (char**)malloc(found.size() * sizeof(DWORD)); // array of pointers - - for (auto& path : found) - { - char* str = (char*)malloc(path.length() + 1); - strcpy(str, path.c_str()); - - result.strings[result.count] = str; - result.count++; - } + FindClose(hSearch); - return result; + return CreateStringList(found); } }