| 1762 | } |
| 1763 | |
| 1764 | std::vector<FolderMemoryCard::EnumeratedFileEntry> FolderMemoryCard::GetOrderedFiles(const std::string& dirPath) const |
| 1765 | { |
| 1766 | std::vector<EnumeratedFileEntry> result; |
| 1767 | |
| 1768 | FileSystem::FindResultsArray results; |
| 1769 | FileSystem::FindFiles(dirPath.c_str(), "*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_FOLDERS | FILESYSTEM_FIND_RELATIVE_PATHS | FILESYSTEM_FIND_HIDDEN_FILES, &results); |
| 1770 | if (!results.empty()) |
| 1771 | { |
| 1772 | // We must be able to support legacy folder memcards without the index file, so for those |
| 1773 | // track an order variable and make it negative - this way new files get their order preserved |
| 1774 | // and old files are listed first. |
| 1775 | // In the YAML File order is stored as an unsigned int, so use a signed int64_t to accommodate for |
| 1776 | // all possible values without cutting them off |
| 1777 | // Also exploit the fact pairs sort lexicographically to ensure directories are listed first |
| 1778 | // (since they don't carry their own order in the index file) |
| 1779 | std::map<std::pair<bool, int64_t>, EnumeratedFileEntry> sortContainer; |
| 1780 | int64_t orderForDirectories = 1; |
| 1781 | int64_t orderForLegacyFiles = -1; |
| 1782 | |
| 1783 | for (FILESYSTEM_FIND_DATA& fd : results) |
| 1784 | { |
| 1785 | if (fd.FileName.starts_with("_pcsx2_")) |
| 1786 | continue; |
| 1787 | |
| 1788 | std::string filePath(Path::Combine(dirPath, fd.FileName)); |
| 1789 | if (!(fd.Attributes & FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY)) |
| 1790 | { |
| 1791 | std::optional<ryml::Tree> yaml = loadYamlFile(Path::Combine(dirPath, "_pcsx2_index").c_str()); |
| 1792 | |
| 1793 | EnumeratedFileEntry entry{fd.FileName, fd.CreationTime, fd.ModificationTime, true}; |
| 1794 | int64_t newOrder = orderForLegacyFiles--; |
| 1795 | if (yaml.has_value() && !yaml.value().empty()) |
| 1796 | { |
| 1797 | ryml::NodeRef index = yaml.value().rootref(); |
| 1798 | for (const auto& n : index.children()) |
| 1799 | { |
| 1800 | auto key = std::string(n.key().str, n.key().len); |
| 1801 | } |
| 1802 | if (index.has_child(ryml::to_csubstr(fd.FileName))) |
| 1803 | { |
| 1804 | const auto& node = index[ryml::to_csubstr(fd.FileName)]; |
| 1805 | if (node.has_child("timeCreated")) |
| 1806 | { |
| 1807 | node["timeCreated"] >> entry.m_timeCreated; |
| 1808 | } |
| 1809 | if (node.has_child("timeModified")) |
| 1810 | { |
| 1811 | node["timeModified"] >> entry.m_timeModified; |
| 1812 | } |
| 1813 | if (node.has_child("order")) |
| 1814 | { |
| 1815 | node["order"] >> newOrder; |
| 1816 | } |
| 1817 | } |
| 1818 | } |
| 1819 | |
| 1820 | // orderForLegacyFiles will decrement even if it ends up being unused, but that's fine |
| 1821 | auto key = std::make_pair(true, newOrder); |