2023-04-21 15:02:39 +02:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "games_config.h"
|
|
|
|
|
#include "util/logs.hpp"
|
|
|
|
|
#include "util/yaml.hpp"
|
|
|
|
|
#include "Utilities/File.h"
|
|
|
|
|
|
|
|
|
|
LOG_CHANNEL(cfg_log, "CFG");
|
|
|
|
|
|
|
|
|
|
games_config::games_config()
|
|
|
|
|
{
|
|
|
|
|
load();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
games_config::~games_config()
|
|
|
|
|
{
|
|
|
|
|
if (m_dirty)
|
|
|
|
|
{
|
|
|
|
|
save();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-26 23:13:28 +02:00
|
|
|
const std::map<std::string, std::string> games_config::get_games() const
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
|
return m_games;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-21 15:02:39 +02:00
|
|
|
std::string games_config::get_path(const std::string& title_id) const
|
|
|
|
|
{
|
|
|
|
|
if (title_id.empty())
|
|
|
|
|
{
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-26 23:13:28 +02:00
|
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
|
|
2023-04-21 15:02:39 +02:00
|
|
|
if (const auto it = m_games.find(title_id); it != m_games.cend())
|
|
|
|
|
{
|
|
|
|
|
return it->second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-22 21:40:36 +01:00
|
|
|
games_config::result games_config::add_game(const std::string& key, const std::string& path)
|
2023-04-21 15:02:39 +02:00
|
|
|
{
|
2023-04-26 23:13:28 +02:00
|
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
|
|
2023-04-21 15:02:39 +02:00
|
|
|
// Access or create node if does not exist
|
|
|
|
|
if (auto it = m_games.find(key); it != m_games.end())
|
|
|
|
|
{
|
|
|
|
|
if (it->second == path)
|
|
|
|
|
{
|
|
|
|
|
// Nothing to do
|
2024-01-22 21:40:36 +01:00
|
|
|
return result::exists;
|
2023-04-21 15:02:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it->second = path;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_games.emplace(key, path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_dirty = true;
|
|
|
|
|
|
2024-01-22 21:40:36 +01:00
|
|
|
if (m_save_on_dirty && !save_nl())
|
2023-04-21 15:02:39 +02:00
|
|
|
{
|
2024-01-22 21:40:36 +01:00
|
|
|
return result::failure;
|
2023-04-21 15:02:39 +02:00
|
|
|
}
|
|
|
|
|
|
2024-01-22 21:40:36 +01:00
|
|
|
return result::success;
|
2023-04-21 15:02:39 +02:00
|
|
|
}
|
|
|
|
|
|
2024-01-22 21:40:36 +01:00
|
|
|
games_config::result games_config::add_external_hdd_game(const std::string& key, std::string& path)
|
2023-04-25 03:41:03 +02:00
|
|
|
{
|
|
|
|
|
// Don't use the C00 subdirectory in our game list
|
|
|
|
|
if (path.ends_with("/C00") || path.ends_with("\\C00"))
|
|
|
|
|
{
|
|
|
|
|
path = path.substr(0, path.size() - 4);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-22 21:40:36 +01:00
|
|
|
const result res = add_game(key, path);
|
|
|
|
|
|
|
|
|
|
switch (res)
|
2023-04-25 03:41:03 +02:00
|
|
|
{
|
2024-01-22 21:40:36 +01:00
|
|
|
case result::failure:
|
|
|
|
|
cfg_log.error("Failed to save HG game location of title '%s' (error=%s)", key, fs::g_tls_error);
|
|
|
|
|
break;
|
|
|
|
|
case result::success:
|
2023-04-25 03:41:03 +02:00
|
|
|
cfg_log.notice("Registered HG game directory for title '%s': %s", key, path);
|
2024-01-22 21:40:36 +01:00
|
|
|
break;
|
|
|
|
|
case result::exists:
|
|
|
|
|
break;
|
2023-04-25 03:41:03 +02:00
|
|
|
}
|
|
|
|
|
|
2024-01-22 21:40:36 +01:00
|
|
|
return res;
|
2023-04-25 03:41:03 +02:00
|
|
|
}
|
|
|
|
|
|
2023-05-02 03:04:34 +02:00
|
|
|
bool games_config::save_nl()
|
2023-04-21 15:02:39 +02:00
|
|
|
{
|
|
|
|
|
YAML::Emitter out;
|
|
|
|
|
out << m_games;
|
|
|
|
|
|
|
|
|
|
fs::pending_file temp(fs::get_config_dir() + "/games.yml");
|
|
|
|
|
|
2024-01-01 23:59:27 +01:00
|
|
|
if (temp.file && temp.file.write(out.c_str(), out.size()) >= out.size() && temp.commit())
|
2023-04-21 15:02:39 +02:00
|
|
|
{
|
|
|
|
|
m_dirty = false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cfg_log.error("Failed to save games.yml: %s", fs::g_tls_error);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-02 03:04:34 +02:00
|
|
|
bool games_config::save()
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
|
return save_nl();
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-21 15:02:39 +02:00
|
|
|
void games_config::load()
|
|
|
|
|
{
|
2023-04-26 23:13:28 +02:00
|
|
|
std::lock_guard lock(m_mutex);
|
|
|
|
|
|
2023-04-21 15:02:39 +02:00
|
|
|
m_games.clear();
|
|
|
|
|
|
|
|
|
|
if (fs::file f{fs::get_config_dir() + "/games.yml", fs::read + fs::create})
|
|
|
|
|
{
|
|
|
|
|
auto [result, error] = yaml_load(f.to_string());
|
|
|
|
|
|
|
|
|
|
if (!error.empty())
|
|
|
|
|
{
|
|
|
|
|
cfg_log.error("Failed to load games.yml: %s", error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!result.IsMap())
|
|
|
|
|
{
|
|
|
|
|
if (!result.IsNull())
|
|
|
|
|
{
|
|
|
|
|
cfg_log.error("Failed to load games.yml: type %d not a map", result.Type());
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const auto& entry : result)
|
|
|
|
|
{
|
|
|
|
|
if (!entry.first.Scalar().empty() && entry.second.IsScalar() && !entry.second.Scalar().empty())
|
|
|
|
|
{
|
|
|
|
|
m_games.emplace(entry.first.Scalar(), entry.second.Scalar());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|