input_profiles.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <fmt/format.h>
  4. #include "common/fs/fs.h"
  5. #include "common/fs/path_util.h"
  6. #include "yuzu/configuration/config.h"
  7. #include "yuzu/configuration/input_profiles.h"
  8. namespace FS = Common::FS;
  9. namespace {
  10. bool ProfileExistsInFilesystem(std::string_view profile_name) {
  11. return FS::Exists(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "input" /
  12. fmt::format("{}.ini", profile_name));
  13. }
  14. bool IsINI(const std::filesystem::path& filename) {
  15. return filename.extension() == ".ini";
  16. }
  17. std::filesystem::path GetNameWithoutExtension(std::filesystem::path filename) {
  18. return filename.replace_extension();
  19. }
  20. } // namespace
  21. InputProfiles::InputProfiles() {
  22. const auto input_profile_loc = FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "input";
  23. if (!FS::IsDir(input_profile_loc)) {
  24. return;
  25. }
  26. FS::IterateDirEntries(
  27. input_profile_loc,
  28. [this](const std::filesystem::path& full_path) {
  29. const auto filename = full_path.filename();
  30. const auto name_without_ext =
  31. Common::FS::PathToUTF8String(GetNameWithoutExtension(filename));
  32. if (IsINI(filename) && IsProfileNameValid(name_without_ext)) {
  33. map_profiles.insert_or_assign(
  34. name_without_ext,
  35. std::make_unique<Config>(name_without_ext, Config::ConfigType::InputProfile));
  36. }
  37. return true;
  38. },
  39. FS::DirEntryFilter::File);
  40. }
  41. InputProfiles::~InputProfiles() = default;
  42. std::vector<std::string> InputProfiles::GetInputProfileNames() {
  43. std::vector<std::string> profile_names;
  44. profile_names.reserve(map_profiles.size());
  45. for (const auto& [profile_name, config] : map_profiles) {
  46. if (!ProfileExistsInFilesystem(profile_name)) {
  47. DeleteProfile(profile_name);
  48. continue;
  49. }
  50. profile_names.push_back(profile_name);
  51. }
  52. return profile_names;
  53. }
  54. bool InputProfiles::IsProfileNameValid(std::string_view profile_name) {
  55. return profile_name.find_first_of("<>:;\"/\\|,.!?*") == std::string::npos;
  56. }
  57. bool InputProfiles::CreateProfile(const std::string& profile_name, std::size_t player_index) {
  58. if (ProfileExistsInMap(profile_name)) {
  59. return false;
  60. }
  61. map_profiles.insert_or_assign(
  62. profile_name, std::make_unique<Config>(profile_name, Config::ConfigType::InputProfile));
  63. return SaveProfile(profile_name, player_index);
  64. }
  65. bool InputProfiles::DeleteProfile(const std::string& profile_name) {
  66. if (!ProfileExistsInMap(profile_name)) {
  67. return false;
  68. }
  69. if (!ProfileExistsInFilesystem(profile_name) ||
  70. FS::RemoveFile(map_profiles[profile_name]->GetConfigFilePath())) {
  71. map_profiles.erase(profile_name);
  72. }
  73. return !ProfileExistsInMap(profile_name) && !ProfileExistsInFilesystem(profile_name);
  74. }
  75. bool InputProfiles::LoadProfile(const std::string& profile_name, std::size_t player_index) {
  76. if (!ProfileExistsInMap(profile_name)) {
  77. return false;
  78. }
  79. if (!ProfileExistsInFilesystem(profile_name)) {
  80. map_profiles.erase(profile_name);
  81. return false;
  82. }
  83. map_profiles[profile_name]->ReadControlPlayerValue(player_index);
  84. return true;
  85. }
  86. bool InputProfiles::SaveProfile(const std::string& profile_name, std::size_t player_index) {
  87. if (!ProfileExistsInMap(profile_name)) {
  88. return false;
  89. }
  90. map_profiles[profile_name]->SaveControlPlayerValue(player_index);
  91. return true;
  92. }
  93. bool InputProfiles::ProfileExistsInMap(const std::string& profile_name) const {
  94. return map_profiles.find(profile_name) != map_profiles.end();
  95. }