From 5ff0547d190bff00c9d3d989245dd68ab158c054 Mon Sep 17 00:00:00 2001 From: jw098 Date: Mon, 20 Apr 2026 12:48:04 -0700 Subject: [PATCH] ResourceDownloadHelpers --- .../ResourceDownloadHelpers.cpp | 130 ++++++++++++++++++ .../ResourceDownloadHelpers.h | 56 ++++++++ SerialPrograms/cmake/SourceFiles.cmake | 2 + 3 files changed, 188 insertions(+) create mode 100644 SerialPrograms/Source/CommonFramework/ResourceDownload/ResourceDownloadHelpers.cpp create mode 100644 SerialPrograms/Source/CommonFramework/ResourceDownload/ResourceDownloadHelpers.h diff --git a/SerialPrograms/Source/CommonFramework/ResourceDownload/ResourceDownloadHelpers.cpp b/SerialPrograms/Source/CommonFramework/ResourceDownload/ResourceDownloadHelpers.cpp new file mode 100644 index 0000000000..6a29c02bb5 --- /dev/null +++ b/SerialPrograms/Source/CommonFramework/ResourceDownload/ResourceDownloadHelpers.cpp @@ -0,0 +1,130 @@ +/* Resource Download Helpers + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "CommonFramework/Globals.h" +#include "CommonFramework/Logging/Logger.h" +// #include "CommonFramework/Tools/GlobalThreadPools.h" +#include "CommonFramework/Tools/FileDownloader.h" +#include "CommonFramework/Exceptions/OperationFailedException.h" +#include "Common/Cpp/Json/JsonArray.h" +#include "Common/Cpp/Json/JsonObject.h" +#include "Common/Cpp/Filesystem.h" +#include "ResourceDownloadHelpers.h" + +// #include +// #include +// #include + +#include +using std::cout; +using std::endl; + +namespace PokemonAutomation{ + + +std::vector deserialize_resource_list_json(const JsonValue& json){ + std::vector resources; + + try{ + const JsonObject& obj = json.to_object_throw(); + const JsonArray& resource_list = obj.get_array_throw("ResourceList"); + for (const JsonValue& resource_val : resource_list){ + const JsonObject& resource_obj = resource_val.to_object_throw(); + + std::string resource_name = resource_obj.get_string_throw("ResourceName"); + std::optional version_num = (uint16_t)resource_obj.get_integer_throw("Version"); + size_t compressed_bytes = (size_t)resource_obj.get_integer_throw("CompressedBytes"); + size_t decompressed_bytes = (size_t)resource_obj.get_integer_throw("DecompressedBytes"); + std::string url = resource_obj.get_string_throw("URL"); + std::string sha256 = resource_obj.get_string_throw("SHA256"); + + DownloadedResourceMetadata resource = { + resource_name, + version_num, + compressed_bytes, + decompressed_bytes, + url, + sha256 + }; + + resources.emplace_back(std::move(resource)); + + } + + }catch (ParseException&){ + std::cerr << "JSON parsing error. Given JSON file doesn't match the expected format." << endl; + // throw ParseException("JSON parsing error. Given JSON file doesn't match the expected format."); + return std::vector(); + } + + return resources; +} + + +const std::vector& local_resource_download_list(){ + // cout << "local_resource_download_list" << endl; + static std::vector local_resources = deserialize_resource_list_json(load_json_file(RESOURCE_PATH() + "ResourceDownloadList.json")); + + return local_resources; +} + + +JsonValue fetch_resource_download_list_json_from_remote(){ + Logger& logger = global_logger_tagged(); + JsonValue json = + FileDownloader::download_json_file( + logger, + "https://raw.githubusercontent.com/jw098/Packages/refs/heads/download/Resources/ResourceDownloadList.json" + ); + + return json; +} + +const JsonValue& remote_resource_download_list_json(){ + static const JsonValue json = fetch_resource_download_list_json_from_remote(); + + return json; +} + +const std::vector& remote_resource_download_list(){ + // cout << "remote_resource_download_list" << endl; + static std::vector remote_resources = deserialize_resource_list_json(remote_resource_download_list_json()); + + return remote_resources; +} + +std::optional get_resource_version_num(Filesystem::Path folder_path){ + try{ + std::string file_name = folder_path.string() + "/version.json"; + const JsonValue& json = load_json_file(file_name); + + const JsonObject& obj = json.to_object_throw(); + uint16_t version_num = (uint16_t)obj.get_integer_throw("version"); + return version_num; + }catch(...){ + std::cerr << "Unable to determine the version number from version.json." << endl; + return std::nullopt; + } + +} + +ResourceVersionStatus get_version_status(uint16_t expected_version_num, std::optional current_version_num){ + if (!current_version_num.has_value()){ + return ResourceVersionStatus::NOT_APPLICABLE; + } + + if (current_version_num < expected_version_num){ + return ResourceVersionStatus::OUTDATED; + }else if (current_version_num == expected_version_num){ + return ResourceVersionStatus::CURRENT; + }else{ // current > expected + return ResourceVersionStatus::FUTURE_VERSION; + } +} + + + +} diff --git a/SerialPrograms/Source/CommonFramework/ResourceDownload/ResourceDownloadHelpers.h b/SerialPrograms/Source/CommonFramework/ResourceDownload/ResourceDownloadHelpers.h new file mode 100644 index 0000000000..f0305bde6b --- /dev/null +++ b/SerialPrograms/Source/CommonFramework/ResourceDownload/ResourceDownloadHelpers.h @@ -0,0 +1,56 @@ +/* Resource Download Helpers + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_ResourceDownloadHelpers_H +#define PokemonAutomation_ResourceDownloadHelpers_H + +#include +#include + + +namespace PokemonAutomation{ + +namespace Filesystem{ + class Path; +} + + + +struct DownloadedResourceMetadata{ + std::string resource_name; + std::optional version_num; + size_t size_compressed_bytes; + size_t size_decompressed_bytes; + std::string url; + std::string sha256; +}; + +enum class ResourceVersionStatus{ + CURRENT, + OUTDATED, // still used, but newer version available + FUTURE_VERSION, // current version number is greater than the expected version number + NOT_APPLICABLE, // resource not downloaded locally, so can't get its version + // RETIRED, // no longer used +}; + +enum class RemoteMetadataStatus{ + UNINITIALIZED, + NOT_AVAILABLE, + AVAILABLE, +}; +struct RemoteMetadata { + RemoteMetadataStatus status = RemoteMetadataStatus::UNINITIALIZED; + DownloadedResourceMetadata metadata; +}; + + +const std::vector& local_resource_download_list(); +const std::vector& remote_resource_download_list(); +std::optional get_resource_version_num(Filesystem::Path folder_path); +ResourceVersionStatus get_version_status(uint16_t expected_version_num, std::optional current_version_num); + +} +#endif diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index ffe3441ea2..54590f4c88 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -487,6 +487,8 @@ file(GLOB LIBRARY_SOURCES Source/CommonFramework/Recording/StreamHistoryTracker_SaveFrames.h Source/CommonFramework/Recording/StreamRecorder.cpp Source/CommonFramework/Recording/StreamRecorder.h + Source/CommonFramework/ResourceDownload/ResourceDownloadHelpers.cpp + Source/CommonFramework/ResourceDownload/ResourceDownloadHelpers.h Source/CommonFramework/Startup/NewVersionCheck.cpp Source/CommonFramework/Startup/NewVersionCheck.h Source/CommonFramework/Startup/SetupSettings.cpp