diff --git a/dll/dll/steam_remote_storage.h b/dll/dll/steam_remote_storage.h index 97b45918..3278adf4 100644 --- a/dll/dll/steam_remote_storage.h +++ b/dll/dll/steam_remote_storage.h @@ -86,27 +86,22 @@ public ISteamRemoteStorage private: class Settings *settings; class Ugc_Remote_Storage_Bridge *ugc_bridge; - Local_Storage *local_storage; + class Local_Storage *local_storage; class SteamCallResults *callback_results; bool steam_cloud_enabled; std::vector async_reads; std::vector stream_writes; std::map shared_files; std::map downloaded_files; - std::set subscribed; // just to keep the running state of subscription public: -Steam_Remote_Storage(class Settings *settings, class Ugc_Remote_Storage_Bridge *ugc_bridge, Local_Storage *local_storage, class SteamCallResults *callback_results) +Steam_Remote_Storage(class Settings *settings, class Ugc_Remote_Storage_Bridge *ugc_bridge, class Local_Storage *local_storage, class SteamCallResults *callback_results) { this->settings = settings; this->ugc_bridge = ugc_bridge; this->local_storage = local_storage; this->callback_results = callback_results; steam_cloud_enabled = true; - local_storage->update_save_filenames(Local_Storage::remote_storage_folder); - - // subscribe to all mods initially - subscribed = settings->modSet(); } // NOTE @@ -919,7 +914,7 @@ SteamAPICall_t SubscribePublishedFile( PublishedFileId_t unPublishedFileId ) if (settings->isModInstalled(unPublishedFileId)) { data.m_eResult = EResult::k_EResultOK; - subscribed.insert(unPublishedFileId); + ugc_bridge->add_subbed_mod(unPublishedFileId); } else { data.m_eResult = EResult::k_EResultFail; // TODO is this correct? } @@ -935,16 +930,16 @@ SteamAPICall_t EnumerateUserSubscribedFiles( uint32 unStartIndex ) std::lock_guard lock(global_mutex); // Get ready for a working but bad implementation - Detanup01 RemoteStorageEnumerateUserSubscribedFilesResult_t data{}; - uint32_t modCount = (uint32_t)subscribed.size(); + uint32_t modCount = (uint32_t)ugc_bridge->subbed_mods_count(); if (unStartIndex >= modCount) { data.m_eResult = EResult::k_EResultInvalidParam; // is this correct? } else { data.m_eResult = k_EResultOK; data.m_nTotalResultCount = modCount - unStartIndex; // total amount starting from given index - std::set::iterator i = subscribed.begin(); + std::set::iterator i = ugc_bridge->subbed_mods_itr_begin(); std::advance(i, unStartIndex); uint32_t iterated = 0; - for (; i != subscribed.end() && iterated < k_unEnumeratePublishedFilesMaxResults; i++) { + for (; i != ugc_bridge->subbed_mods_itr_end() && iterated < k_unEnumeratePublishedFilesMaxResults; i++) { PublishedFileId_t modId = *i; auto mod = settings->getMod(modId); uint32 time = mod.timeAddedToUserList; //this can be changed, default is 1554997000 @@ -968,9 +963,9 @@ SteamAPICall_t UnsubscribePublishedFile( PublishedFileId_t unPublishedFileId ) RemoteStorageUnsubscribePublishedFileResult_t data{}; data.m_nPublishedFileId = unPublishedFileId; // TODO is this correct? - if (subscribed.count(unPublishedFileId)) { + if (ugc_bridge->has_subbed_mod(unPublishedFileId)) { data.m_eResult = k_EResultOK; - subscribed.erase(unPublishedFileId); + ugc_bridge->remove_subbed_mod(unPublishedFileId); } else { data.m_eResult = k_EResultFail; } diff --git a/dll/dll/steam_ugc.h b/dll/dll/steam_ugc.h index 312bbd82..5ee44b63 100644 --- a/dll/dll/steam_ugc.h +++ b/dll/dll/steam_ugc.h @@ -44,14 +44,17 @@ public ISteamUGC016, public ISteamUGC017, public ISteamUGC { + constexpr static const char ugc_favorits_file[] = "favorites.txt"; + class Settings *settings; - Ugc_Remote_Storage_Bridge *ugc_bridge; + class Ugc_Remote_Storage_Bridge *ugc_bridge; + class Local_Storage *local_storage; class SteamCallResults *callback_results; class SteamCallBacks *callbacks; - std::set subscribed; UGCQueryHandle_t handle = 50; // just makes debugging easier, any initial val is fine, even 1 - std::vector ugc_queries; + std::vector ugc_queries{}; + std::set favorites{}; UGCQueryHandle_t new_ugc_query( bool return_all_subscribed = false, @@ -115,15 +118,52 @@ void set_details(PublishedFileId_t id, SteamUGCDetails_t *pDetails) } } +void read_ugc_favorites() +{ + if (!local_storage->file_exists("", ugc_favorits_file)) return; + + unsigned int size = local_storage->file_size("", ugc_favorits_file); + if (!size) return; + + std::string data(size, '\0'); + int read = local_storage->get_data("", ugc_favorits_file, &data[0], (unsigned int)data.size()); + if ((size_t)read != data.size()) return; + + std::stringstream ss(data); + std::string line{}; + while (std::getline(ss, line)) { + try + { + unsigned long long fav_id = std::stoull(line); + favorites.insert(fav_id); + PRINT_DEBUG("Steam_UGC added item to favorites %llu\n", fav_id); + } catch(...) { } + } + +} + +bool write_ugc_favorites() +{ + std::stringstream ss{}; + for (auto id : favorites) { + ss << id << "\n"; + ss.flush(); + } + auto file_data = ss.str(); + int stored = local_storage->store_data("", ugc_favorits_file, &file_data[0], file_data.size()); + return (size_t)stored == file_data.size(); +} + public: -Steam_UGC(class Settings *settings, class Ugc_Remote_Storage_Bridge *ugc_bridge, class SteamCallResults *callback_results, class SteamCallBacks *callbacks) +Steam_UGC(class Settings *settings, class Ugc_Remote_Storage_Bridge *ugc_bridge, class Local_Storage *local_storage, class SteamCallResults *callback_results, class SteamCallBacks *callbacks) { this->settings = settings; this->ugc_bridge = ugc_bridge; + this->local_storage = local_storage; this->callbacks = callbacks; this->callback_results = callback_results; - subscribed = settings->modSet(); + read_ugc_favorites(); } @@ -174,12 +214,12 @@ SteamAPICall_t SendQueryUGCRequest( UGCQueryHandle_t handle ) return k_uAPICallInvalid; if (request->return_all_subscribed) { - request->results = subscribed; + request->results = std::set(ugc_bridge->subbed_mods_itr_begin(), ugc_bridge->subbed_mods_itr_end()); } if (request->return_only.size()) { for (auto & s : request->return_only) { - if (subscribed.count(s)) { + if (ugc_bridge->has_subbed_mod(s)) { request->results.insert(s); } } @@ -639,7 +679,7 @@ SteamAPICall_t CreateItem( AppId_t nConsumerAppId, EWorkshopFileType eFileType ) PRINT_DEBUG("Steam_UGC::CreateItem\n"); std::lock_guard lock(global_mutex); - return 0; + return k_uAPICallInvalid; } // create new item for this app with no content attached yet @@ -649,7 +689,7 @@ UGCUpdateHandle_t StartItemUpdate( AppId_t nConsumerAppId, PublishedFileId_t nPu PRINT_DEBUG("Steam_UGC::StartItemUpdate\n"); std::lock_guard lock(global_mutex); - return 0; + return k_UGCUpdateHandleInvalid; } // start an UGC item update. Set changed properties before commiting update with CommitItemUpdate() @@ -848,7 +888,7 @@ SteamAPICall_t SubmitItemUpdate( UGCUpdateHandle_t handle, const char *pchChange PRINT_DEBUG("Steam_UGC::SubmitItemUpdate\n"); std::lock_guard lock(global_mutex); - return 0; + return k_uAPICallInvalid; } // commit update process started with StartItemUpdate() @@ -869,8 +909,19 @@ SteamAPICall_t SetUserItemVote( PublishedFileId_t nPublishedFileID, bool bVoteUp { PRINT_DEBUG("Steam_UGC::SetUserItemVote\n"); std::lock_guard lock(global_mutex); + if (!settings->isModInstalled(nPublishedFileID)) return k_uAPICallInvalid; // TODO is this correct - return 0; + auto mod = settings->getMod(nPublishedFileID); + SetUserItemVoteResult_t data{}; + data.m_eResult = EResult::k_EResultOK; + data.m_nPublishedFileId = nPublishedFileID; + if (bVoteUp) { + ++mod.votesUp; + } else { + ++mod.votesDown; + } + settings->addModDetails(nPublishedFileID, mod); + return callback_results->addCallResult(data.k_iCallback, &data, sizeof(data)); } @@ -879,18 +930,41 @@ SteamAPICall_t GetUserItemVote( PublishedFileId_t nPublishedFileID ) { PRINT_DEBUG("Steam_UGC::GetUserItemVote\n"); std::lock_guard lock(global_mutex); - - return 0; + if (nPublishedFileID == k_PublishedFileIdInvalid || !settings->isModInstalled(nPublishedFileID)) return k_uAPICallInvalid; // TODO is this correct + + auto mod = settings->getMod(nPublishedFileID); + GetUserItemVoteResult_t data{}; + data.m_eResult = EResult::k_EResultOK; + data.m_nPublishedFileId = nPublishedFileID; + data.m_bVotedDown = mod.votesDown; + data.m_bVotedUp = mod.votesUp; + data.m_bVoteSkipped = true; + return callback_results->addCallResult(data.k_iCallback, &data, sizeof(data)); } STEAM_CALL_RESULT( UserFavoriteItemsListChanged_t ) SteamAPICall_t AddItemToFavorites( AppId_t nAppId, PublishedFileId_t nPublishedFileID ) { - PRINT_DEBUG("Steam_UGC::AddItemToFavorites\n"); + PRINT_DEBUG("Steam_UGC::AddItemToFavorites %u %llu\n", nAppId, nPublishedFileID); std::lock_guard lock(global_mutex); + if (nAppId == k_uAppIdInvalid || nAppId != settings->get_local_game_id().AppID()) return k_uAPICallInvalid; // TODO is this correct + if (nPublishedFileID == k_PublishedFileIdInvalid || !settings->isModInstalled(nPublishedFileID)) return k_uAPICallInvalid; // TODO is this correct + + UserFavoriteItemsListChanged_t data{}; + data.m_nPublishedFileId = nPublishedFileID; + data.m_bWasAddRequest = true; + + auto add = favorites.insert(nPublishedFileID); + if (add.second) { // if new insertion + PRINT_DEBUG(" adding new item to favorites"); + bool ok = write_ugc_favorites(); + data.m_eResult = ok ? EResult::k_EResultOK : EResult::k_EResultFail; + } else { // nPublishedFileID already exists + data.m_eResult = EResult::k_EResultOK; + } - return 0; + return callback_results->addCallResult(data.k_iCallback, &data, sizeof(data)); } @@ -899,8 +973,23 @@ SteamAPICall_t RemoveItemFromFavorites( AppId_t nAppId, PublishedFileId_t nPubli { PRINT_DEBUG("Steam_UGC::RemoveItemFromFavorites\n"); std::lock_guard lock(global_mutex); + if (nAppId == k_uAppIdInvalid || nAppId != settings->get_local_game_id().AppID()) return k_uAPICallInvalid; // TODO is this correct + if (nPublishedFileID == k_PublishedFileIdInvalid || !settings->isModInstalled(nPublishedFileID)) return k_uAPICallInvalid; // TODO is this correct + + UserFavoriteItemsListChanged_t data{}; + data.m_nPublishedFileId = nPublishedFileID; + data.m_bWasAddRequest = false; + + auto removed = favorites.erase(nPublishedFileID); + if (removed) { + PRINT_DEBUG(" removing item from favorites"); + bool ok = write_ugc_favorites(); + data.m_eResult = ok ? EResult::k_EResultOK : EResult::k_EResultFail; + } else { // nPublishedFileID didn't exist + data.m_eResult = EResult::k_EResultOK; + } - return 0; + return callback_results->addCallResult(data.k_iCallback, &data, sizeof(data)); } @@ -914,7 +1003,7 @@ SteamAPICall_t SubscribeItem( PublishedFileId_t nPublishedFileID ) data.m_nPublishedFileId = nPublishedFileID; if (settings->isModInstalled(nPublishedFileID)) { data.m_eResult = k_EResultOK; - subscribed.insert(nPublishedFileID); + ugc_bridge->add_subbed_mod(nPublishedFileID); } else { data.m_eResult = k_EResultFail; } @@ -929,11 +1018,11 @@ SteamAPICall_t UnsubscribeItem( PublishedFileId_t nPublishedFileID ) std::lock_guard lock(global_mutex); RemoteStorageUnsubscribePublishedFileResult_t data; data.m_nPublishedFileId = nPublishedFileID; - if (subscribed.count(nPublishedFileID) == 0) { + if (!ugc_bridge->has_subbed_mod(nPublishedFileID)) { data.m_eResult = k_EResultFail; //TODO: check if this is accurate } else { data.m_eResult = k_EResultOK; - subscribed.erase(nPublishedFileID); + ugc_bridge->remove_subbed_mod(nPublishedFileID); } return callback_results->addCallResult(data.k_iCallback, &data, sizeof(data)); @@ -945,8 +1034,8 @@ uint32 GetNumSubscribedItems() PRINT_DEBUG("Steam_UGC::GetNumSubscribedItems\n"); std::lock_guard lock(global_mutex); - PRINT_DEBUG(" Steam_UGC::GetNumSubscribedItems = %zu\n", subscribed.size()); - return subscribed.size(); + PRINT_DEBUG(" Steam_UGC::GetNumSubscribedItems = %zu\n", ugc_bridge->subbed_mods_count()); + return (uint32)ugc_bridge->subbed_mods_count(); } // number of subscribed items @@ -954,11 +1043,11 @@ uint32 GetSubscribedItems( PublishedFileId_t* pvecPublishedFileID, uint32 cMaxEn { PRINT_DEBUG("Steam_UGC::GetSubscribedItems %p %u\n", pvecPublishedFileID, cMaxEntries); std::lock_guard lock(global_mutex); - if (cMaxEntries > subscribed.size()) { - cMaxEntries = subscribed.size(); + if ((size_t)cMaxEntries > ugc_bridge->subbed_mods_count()) { + cMaxEntries = (uint32)ugc_bridge->subbed_mods_count(); } - std::copy_n(subscribed.begin(), cMaxEntries, pvecPublishedFileID); + std::copy_n(ugc_bridge->subbed_mods_itr_begin(), cMaxEntries, pvecPublishedFileID); return cMaxEntries; } // all subscribed item PublishFileIDs @@ -968,14 +1057,17 @@ uint32 GetItemState( PublishedFileId_t nPublishedFileID ) { PRINT_DEBUG("Steam_UGC::GetItemState %llu\n", nPublishedFileID); std::lock_guard lock(global_mutex); - if (subscribed.count(nPublishedFileID)) { + if (ugc_bridge->has_subbed_mod(nPublishedFileID)) { if (settings->isModInstalled(nPublishedFileID)) { - return k_EItemStateInstalled | k_EItemStateSubscribed; + PRINT_DEBUG(" mod is subscribed and installed\n"); + return k_EItemStateInstalled | k_EItemStateSubscribed | k_EItemStateLegacyItem; } + PRINT_DEBUG(" mod is subscribed\n"); return k_EItemStateSubscribed; } + PRINT_DEBUG(" mod isn't found\n"); return k_EItemStateNone; } @@ -984,16 +1076,17 @@ uint32 GetItemState( PublishedFileId_t nPublishedFileID ) // if k_EItemStateLegacyItem is set, pchFolder contains the path to the legacy file itself (not a folder) bool GetItemInstallInfo( PublishedFileId_t nPublishedFileID, uint64 *punSizeOnDisk, STEAM_OUT_STRING_COUNT( cchFolderSize ) char *pchFolder, uint32 cchFolderSize, uint32 *punTimeStamp ) { - PRINT_DEBUG("Steam_UGC::GetItemInstallInfo %llu\n", nPublishedFileID); + PRINT_DEBUG("Steam_UGC::GetItemInstallInfo %llu %p %p %u %p\n", nPublishedFileID, punSizeOnDisk, pchFolder, cchFolderSize, punTimeStamp); std::lock_guard lock(global_mutex); - if (!settings->isModInstalled(nPublishedFileID)) { - return false; - } + if (!cchFolderSize) return false; + if (!settings->isModInstalled(nPublishedFileID)) return false; auto mod = settings->getMod(nPublishedFileID); if (punSizeOnDisk) *punSizeOnDisk = mod.primaryFileSize; - if (punTimeStamp) *punTimeStamp = mod.timeCreated; + if (punTimeStamp) *punTimeStamp = mod.timeUpdated; if (pchFolder && cchFolderSize) { + PRINT_DEBUG(" mod path: '%s'\n", mod.path.c_str()); + memset(pchFolder, cchFolderSize, 0); mod.path.copy(pchFolder, cchFolderSize - 1); } diff --git a/dll/dll/ugc_remote_storage_bridge.h b/dll/dll/ugc_remote_storage_bridge.h index d19bb85f..d60838d1 100644 --- a/dll/dll/ugc_remote_storage_bridge.h +++ b/dll/dll/ugc_remote_storage_bridge.h @@ -13,17 +13,26 @@ public: }; private: + class Settings *settings; // key: UGCHandle_t which is the file handle (primary or preview) // value: the mod id, true if UGCHandle_t of primary file | false if UGCHandle_t of preview file std::map steam_ugc_queries{}; + std::set subscribed; // just to keep the running state of subscription public: + Ugc_Remote_Storage_Bridge(class Settings *settings); + // called from Steam_UGC::SendQueryUGCRequest() after a successful query void add_ugc_query_result(UGCHandle_t file_handle, PublishedFileId_t fileid, bool handle_of_primary_file); - bool remove_ugc_query_result(UGCHandle_t file_handle); + std::optional get_ugc_query_result(UGCHandle_t file_handle) const; - std::optional get_ugc_query_result(UGCHandle_t file_handle); + void add_subbed_mod(PublishedFileId_t id); + void remove_subbed_mod(PublishedFileId_t id); + size_t subbed_mods_count() const; + bool has_subbed_mod(PublishedFileId_t id) const; + std::set::iterator subbed_mods_itr_begin() const; + std::set::iterator subbed_mods_itr_end() const; ~Ugc_Remote_Storage_Bridge(); }; diff --git a/dll/local_storage.cpp b/dll/local_storage.cpp index 34798cc4..5aff27b1 100644 --- a/dll/local_storage.cpp +++ b/dll/local_storage.cpp @@ -571,7 +571,7 @@ std::vector Local_Storage::get_filenames_path(std::string path) int Local_Storage::store_data(std::string folder, std::string file, char *data, unsigned int length) { - if (folder.back() != *PATH_SEPARATOR) { + if (folder.size() && folder.back() != *PATH_SEPARATOR) { folder.append(PATH_SEPARATOR); } @@ -599,7 +599,7 @@ int Local_Storage::get_file_data(std::string full_path, char *data, unsigned int int Local_Storage::get_data(std::string folder, std::string file, char *data, unsigned int max_length, unsigned int offset) { file = sanitize_file_name(file); - if (folder.back() != *PATH_SEPARATOR) { + if (folder.size() && folder.back() != *PATH_SEPARATOR) { folder.append(PATH_SEPARATOR); } @@ -616,7 +616,7 @@ int Local_Storage::get_data_settings(std::string file, char *data, unsigned int int Local_Storage::count_files(std::string folder) { - if (folder.back() != *PATH_SEPARATOR) { + if (folder.size() && folder.back() != *PATH_SEPARATOR) { folder.append(PATH_SEPARATOR); } @@ -626,7 +626,7 @@ int Local_Storage::count_files(std::string folder) bool Local_Storage::file_exists(std::string folder, std::string file) { file = sanitize_file_name(file); - if (folder.back() != *PATH_SEPARATOR) { + if (folder.size() && folder.back() != *PATH_SEPARATOR) { folder.append(PATH_SEPARATOR); } @@ -637,7 +637,7 @@ bool Local_Storage::file_exists(std::string folder, std::string file) unsigned int Local_Storage::file_size(std::string folder, std::string file) { file = sanitize_file_name(file); - if (folder.back() != *PATH_SEPARATOR) { + if (folder.size() && folder.back() != *PATH_SEPARATOR) { folder.append(PATH_SEPARATOR); } @@ -648,7 +648,7 @@ unsigned int Local_Storage::file_size(std::string folder, std::string file) bool Local_Storage::file_delete(std::string folder, std::string file) { file = sanitize_file_name(file); - if (folder.back() != *PATH_SEPARATOR) { + if (folder.size() && folder.back() != *PATH_SEPARATOR) { folder.append(PATH_SEPARATOR); } @@ -663,7 +663,7 @@ bool Local_Storage::file_delete(std::string folder, std::string file) uint64_t Local_Storage::file_timestamp(std::string folder, std::string file) { file = sanitize_file_name(file); - if (folder.back() != *PATH_SEPARATOR) { + if (folder.size() && folder.back() != *PATH_SEPARATOR) { folder.append(PATH_SEPARATOR); } @@ -681,7 +681,7 @@ uint64_t Local_Storage::file_timestamp(std::string folder, std::string file) bool Local_Storage::iterate_file(std::string folder, int index, char *output_filename, int32 *output_size) { - if (folder.back() != *PATH_SEPARATOR) { + if (folder.size() && folder.back() != *PATH_SEPARATOR) { folder.append(PATH_SEPARATOR); } diff --git a/dll/steam_client.cpp b/dll/steam_client.cpp index c1313c23..d5f1a45a 100644 --- a/dll/steam_client.cpp +++ b/dll/steam_client.cpp @@ -51,6 +51,7 @@ static void background_thread(Steam_Client *client) Steam_Client::Steam_Client() { uint32 appid = create_localstorage_settings(&settings_client, &settings_server, &local_storage); + local_storage->update_save_filenames(Local_Storage::remote_storage_folder); network = new Networking(settings_server->get_local_steam_id(), appid, settings_server->get_port(), &(settings_server->custom_broadcasts), settings_server->disable_networking); @@ -74,7 +75,7 @@ Steam_Client::Steam_Client() steam_friends = new Steam_Friends(settings_client, network, callback_results_client, callbacks_client, run_every_runcb, steam_overlay); steam_utils = new Steam_Utils(settings_client, callback_results_client, steam_overlay); - ugc_bridge = new Ugc_Remote_Storage_Bridge(); + ugc_bridge = new Ugc_Remote_Storage_Bridge(settings_client); steam_matchmaking = new Steam_Matchmaking(settings_client, network, callback_results_client, callbacks_client, run_every_runcb); steam_matchmaking_servers = new Steam_Matchmaking_Servers(settings_client, network); @@ -85,7 +86,7 @@ Steam_Client::Steam_Client() steam_screenshots = new Steam_Screenshots(local_storage, callbacks_client); steam_http = new Steam_HTTP(settings_client, network, callback_results_client, callbacks_client); steam_controller = new Steam_Controller(settings_client, callback_results_client, callbacks_client, run_every_runcb); - steam_ugc = new Steam_UGC(settings_client, ugc_bridge, callback_results_client, callbacks_client); + steam_ugc = new Steam_UGC(settings_client, ugc_bridge, local_storage, callback_results_client, callbacks_client); steam_applist = new Steam_Applist(); steam_music = new Steam_Music(callbacks_client); steam_musicremote = new Steam_MusicRemote(); @@ -111,7 +112,7 @@ Steam_Client::Steam_Client() steam_gameserver_networking = new Steam_Networking(settings_server, network, callbacks_server, run_every_runcb); steam_gameserver_http = new Steam_HTTP(settings_server, network, callback_results_server, callbacks_server); steam_gameserver_inventory = new Steam_Inventory(settings_server, callback_results_server, callbacks_server, run_every_runcb, local_storage); - steam_gameserver_ugc = new Steam_UGC(settings_server, ugc_bridge, callback_results_server, callbacks_server); + steam_gameserver_ugc = new Steam_UGC(settings_server, ugc_bridge, local_storage, callback_results_server, callbacks_server); steam_gameserver_apps = new Steam_Apps(settings_server, callback_results_server); steam_gameserver_networking_sockets = new Steam_Networking_Sockets(settings_server, network, callback_results_server, callbacks_server, run_every_runcb, steam_networking_sockets->get_shared_between_client_server()); steam_gameserver_networking_sockets_serialized = new Steam_Networking_Sockets_Serialized(settings_server, network, callback_results_server, callbacks_server, run_every_runcb); diff --git a/dll/ugc_remote_storage_bridge.cpp b/dll/ugc_remote_storage_bridge.cpp index 20108a8a..7e747e9b 100644 --- a/dll/ugc_remote_storage_bridge.cpp +++ b/dll/ugc_remote_storage_bridge.cpp @@ -1,6 +1,14 @@ #include "dll/ugc_remote_storage_bridge.h" +Ugc_Remote_Storage_Bridge::Ugc_Remote_Storage_Bridge(class Settings *settings) +{ + this->settings = settings; + + // subscribe to all mods initially + subscribed = settings->modSet(); +} + void Ugc_Remote_Storage_Bridge::add_ugc_query_result(UGCHandle_t file_handle, PublishedFileId_t fileid, bool handle_of_primary_file) { std::lock_guard lock(global_mutex); @@ -16,7 +24,7 @@ bool Ugc_Remote_Storage_Bridge::remove_ugc_query_result(UGCHandle_t file_handle) return !!steam_ugc_queries.erase(file_handle); } -std::optional Ugc_Remote_Storage_Bridge::get_ugc_query_result(UGCHandle_t file_handle) +std::optional Ugc_Remote_Storage_Bridge::get_ugc_query_result(UGCHandle_t file_handle) const { std::lock_guard lock(global_mutex); @@ -25,6 +33,36 @@ std::optional Ugc_Remote_Storage_Bridge::g return it->second; } +void Ugc_Remote_Storage_Bridge::add_subbed_mod(PublishedFileId_t id) +{ + subscribed.insert(id); +} + +void Ugc_Remote_Storage_Bridge::remove_subbed_mod(PublishedFileId_t id) +{ + subscribed.erase(id); +} + +size_t Ugc_Remote_Storage_Bridge::subbed_mods_count() const +{ + return subscribed.size(); +} + +bool Ugc_Remote_Storage_Bridge::has_subbed_mod(PublishedFileId_t id) const +{ + return !!subscribed.count(id); +} + +std::set::iterator Ugc_Remote_Storage_Bridge::subbed_mods_itr_begin() const +{ + return subscribed.begin(); +} + +std::set::iterator Ugc_Remote_Storage_Bridge::subbed_mods_itr_end() const +{ + return subscribed.end(); +} + Ugc_Remote_Storage_Bridge::~Ugc_Remote_Storage_Bridge() { std::lock_guard lock(global_mutex); diff --git a/post_build/steam_settings.EXAMPLE/mod_images/12345/Readme.txt b/post_build/steam_settings.EXAMPLE/mod_images.EXAMPLE/12345/Readme.txt similarity index 100% rename from post_build/steam_settings.EXAMPLE/mod_images/12345/Readme.txt rename to post_build/steam_settings.EXAMPLE/mod_images.EXAMPLE/12345/Readme.txt diff --git a/post_build/steam_settings.EXAMPLE/mod_images/12345/my_preview_image.jpg b/post_build/steam_settings.EXAMPLE/mod_images.EXAMPLE/12345/my_preview_image.jpg similarity index 100% rename from post_build/steam_settings.EXAMPLE/mod_images/12345/my_preview_image.jpg rename to post_build/steam_settings.EXAMPLE/mod_images.EXAMPLE/12345/my_preview_image.jpg