8 changed files with 200 additions and 25 deletions
-
2src/core/CMakeLists.txt
-
5src/core/core.cpp
-
3src/core/hle/service/am/service/application_creator.cpp
-
39src/core/hle/service/ns/application_manager_interface.cpp
-
9src/core/hle/service/ns/ns_types.h
-
135src/core/launch_timestamp_cache.cpp
-
13src/core/launch_timestamp_cache.h
-
5src/yuzu/game_list_worker.cpp
@ -0,0 +1,135 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|||
|
|||
#include "core/launch_timestamp_cache.h"
|
|||
|
|||
#include <filesystem>
|
|||
#include <fstream>
|
|||
#include <mutex>
|
|||
#include <sstream>
|
|||
#include <string>
|
|||
#include <unordered_map>
|
|||
|
|||
#include <fmt/format.h>
|
|||
#include <nlohmann/json.hpp>
|
|||
|
|||
#include "common/fs/fs.h"
|
|||
#include "common/fs/file.h"
|
|||
#include "common/fs/path_util.h"
|
|||
#include "common/logging/log.h"
|
|||
|
|||
namespace Core::LaunchTimestampCache { |
|||
namespace { |
|||
|
|||
using CacheMap = std::unordered_map<u64, s64>; |
|||
|
|||
std::mutex mutex; |
|||
CacheMap cache; |
|||
bool loaded = false; |
|||
|
|||
std::filesystem::path GetCachePath() { |
|||
return Common::FS::GetEdenPath(Common::FS::EdenPath::CacheDir) / "launched.json"; |
|||
} |
|||
|
|||
std::optional<std::string> ReadFileToString(const std::filesystem::path& path) { |
|||
const std::ifstream file{path, std::ios::in | std::ios::binary}; |
|||
if (!file) { |
|||
return std::nullopt; |
|||
} |
|||
std::ostringstream ss; |
|||
ss << file.rdbuf(); |
|||
return ss.str(); |
|||
} |
|||
|
|||
bool WriteStringToFile(const std::filesystem::path& path, const std::string& data) { |
|||
if (!Common::FS::CreateParentDirs(path)) { |
|||
return false; |
|||
} |
|||
std::ofstream file{path, std::ios::out | std::ios::binary | std::ios::trunc}; |
|||
if (!file) { |
|||
return false; |
|||
} |
|||
file.write(data.data(), static_cast<std::streamsize>(data.size())); |
|||
return static_cast<bool>(file); |
|||
} |
|||
|
|||
void Load() { |
|||
if (loaded) { |
|||
return; |
|||
} |
|||
|
|||
loaded = true; |
|||
|
|||
const auto path = GetCachePath(); |
|||
if (!std::filesystem::exists(path)) { |
|||
return; |
|||
} |
|||
|
|||
const auto data = ReadFileToString(path); |
|||
if (!data) { |
|||
LOG_WARNING(Core, "Failed to read launch timestamp cache: {}", |
|||
Common::FS::PathToUTF8String(path)); |
|||
return; |
|||
} |
|||
|
|||
try { |
|||
const auto json = nlohmann::json::parse(data->data(), data->data() + data->size()); |
|||
if (!json.is_object()) { |
|||
return; |
|||
} |
|||
for (auto it = json.begin(); it != json.end(); ++it) { |
|||
const auto key_str = it.key(); |
|||
const auto value = it.value(); |
|||
u64 key{}; |
|||
try { |
|||
key = std::stoull(key_str, nullptr, 16); |
|||
} catch (...) { |
|||
continue; |
|||
} |
|||
if (value.is_number_integer()) { |
|||
cache[key] = value.get<s64>(); |
|||
} |
|||
} |
|||
} catch (const std::exception& e) { |
|||
LOG_WARNING(Core, "Failed to parse launch timestamp cache"); |
|||
} |
|||
} |
|||
|
|||
void Save() { |
|||
nlohmann::json json = nlohmann::json::object(); |
|||
for (const auto& [key, value] : cache) { |
|||
json[fmt::format("{:016X}", key)] = value; |
|||
} |
|||
|
|||
const auto path = GetCachePath(); |
|||
if (!WriteStringToFile(path, json.dump(4))) { |
|||
LOG_WARNING(Core, "Failed to write launch timestamp cache: {}", |
|||
Common::FS::PathToUTF8String(path)); |
|||
} |
|||
} |
|||
|
|||
s64 NowSeconds() { |
|||
return std::time(nullptr); |
|||
} |
|||
|
|||
} // namespace
|
|||
|
|||
void SaveLaunchTimestamp(u64 title_id) { |
|||
std::scoped_lock lk{mutex}; |
|||
Load(); |
|||
cache[title_id] = NowSeconds(); |
|||
Save(); |
|||
} |
|||
|
|||
s64 GetLaunchTimestamp(u64 title_id) { |
|||
std::scoped_lock lk{mutex}; |
|||
Load(); |
|||
const auto it = cache.find(title_id); |
|||
if (it != cache.end()) { |
|||
return it->second; |
|||
} |
|||
// we need a timestamp, i decided on 01/01/2026 00:00
|
|||
return 1767225600; |
|||
} |
|||
|
|||
} // namespace Core::LaunchTimestampCache
|
|||
@ -0,0 +1,13 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/common_types.h" |
|||
|
|||
namespace Core::LaunchTimestampCache { |
|||
|
|||
void SaveLaunchTimestamp(u64 title_id); |
|||
s64 GetLaunchTimestamp(u64 title_id); |
|||
|
|||
} // namespace Core::LaunchTimestampCache |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue