| 167 | return false; |
| 168 | } |
| 169 | |
| 170 | std::vector<Mod> ScanModsRoot(const std::string& root, ModSource source) |
| 171 | { |
| 172 | namespace fs = std::filesystem; |
| 173 | std::vector<Mod> mods; |
| 174 | std::error_code ec; |
| 175 | if (!fs::is_directory(root, ec)) |
| 176 | return mods; |
| 177 | |
| 178 | for (fs::directory_iterator it(root, ec), end; it != end; it.increment(ec)) |
| 179 | { |
| 180 | if (ec) |
| 181 | break; |
| 182 | std::error_code dec; |
| 183 | if (!it->is_directory(dec)) |
| 184 | continue; |
| 185 | const std::string folder = it->path().filename().string(); |
| 186 | if (folder.empty() || !LooksLikeMod(it->path().string())) |
| 187 | continue; |
| 188 | |
| 189 | Mod m; |
| 190 | m.id = folder; // the folder name verbatim — any name, '@' optional |
| 191 | m.catalogId = ReadModJsonString(it->path(), "modId"); |
| 192 | m.name = ModDisplayName(folder, ReadModJsonString(it->path(), "name")); |
| 193 | m.version = ReadModJsonString(it->path(), "version"); |
| 194 | m.path = it->path().string(); |
| 195 | m.sizeBytes = DirSizeBytes(it->path()); |
| 196 | m.source = source; |
| 197 | mods.push_back(std::move(m)); |
| 198 | } |
| 199 | |
| 200 | std::sort(mods.begin(), mods.end(), |
| 201 | [](const Mod& a, const Mod& b) { return Foundation::CollateUtf8(a.name.c_str(), b.name.c_str()) < 0; }); |
| 202 | return mods; |
| 203 | } |
| 204 |
no test coverage detected