diff options
| author | Maufeat <sahyno1996@gmail.com> | 2026-01-17 01:48:15 +0100 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-01-17 01:48:15 +0100 |
| commit | ae501e256ea462268dbae8109ad07ef457c4fd8e (patch) | |
| tree | b36691663a10be26462d68f562ad51b8c697ee7b /src/core/launch_timestamp_cache.cpp | |
| parent | b7417f68ce10145e5eb282110e7d50f46ec8047b (diff) | |
[bcat/news/web/am] Implement news applet, proper TLV return, external web browser URL and qlaunch app sorting (#3308)
This pulls eden releases changelog & text from our github releases.
We don't store the msgpack file but rather generate them in-memory for the News Applet.
Uses cache folder. Files generated are:
- cache/news/github_releases.json
- cache/news/eden_logo.jpg
- cache/news/news_read
Additional changes:
- Proper TLV returning for online web applet, to open external URL
- Add applet type `LHub` to properly close, as it also uses TLV return
- qlaunch app sorting, adds another cached .json to track last launched app timestamps and sort them accordingly
Co-authored-by: crueter <crueter@eden-emu.dev>
Co-authored-by: DraVee <dravee@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3308
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: DraVee <dravee@eden-emu.dev>
Reviewed-by: Lizzie <lizzie@eden-emu.dev>
Co-authored-by: Maufeat <sahyno1996@gmail.com>
Co-committed-by: Maufeat <sahyno1996@gmail.com>
Diffstat (limited to 'src/core/launch_timestamp_cache.cpp')
| -rw-r--r-- | src/core/launch_timestamp_cache.cpp | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/core/launch_timestamp_cache.cpp b/src/core/launch_timestamp_cache.cpp new file mode 100644 index 0000000000..5a154a5c2f --- /dev/null +++ b/src/core/launch_timestamp_cache.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 |
