* add 2 new properties to mods.json min_game_branch and max_game_branch according to sdk v1.60, no idea what they do

* make sure buffer is null terminated in `Steam_UGC::GetQueryUGCPreviewURL()`
* implement 2 new useless ugc stuff + use an already made function to check for handle validity
This commit is contained in:
otavepto 2024-07-03 01:35:07 +03:00
parent 3f7ec00719
commit 9443afbd00
6 changed files with 58 additions and 16 deletions

View File

@ -56,6 +56,8 @@ struct Mod_entry {
int32 previewFileSize{}; int32 previewFileSize{};
uint64 total_files_sizes{}; // added in sdk 1.60, "Total size of all files (non-legacy), excluding the preview file" uint64 total_files_sizes{}; // added in sdk 1.60, "Total size of all files (non-legacy), excluding the preview file"
std::string min_game_branch{}; // added in sdk 1.60
std::string max_game_branch{}; // added in sdk 1.60
std::string workshopItemURL{}; std::string workshopItemURL{};

View File

@ -27,6 +27,10 @@ struct UGC_query {
bool return_all_subscribed{}; bool return_all_subscribed{};
std::set<PublishedFileId_t> results{}; std::set<PublishedFileId_t> results{};
bool admin_query = false; // added in sdk 1.60 (currently unused)
std::string min_branch{}; // added in sdk 1.60 (currently unused)
std::string max_branch{}; // added in sdk 1.60 (currently unused)
}; };
class Steam_UGC : class Steam_UGC :
@ -135,6 +139,7 @@ public:
bool GetQueryUGCKeyValueTag( UGCQueryHandle_t handle, uint32 index, const char *pchKey, STEAM_OUT_STRING_COUNT(cchValueSize) char *pchValue, uint32 cchValueSize ); bool GetQueryUGCKeyValueTag( UGCQueryHandle_t handle, uint32 index, const char *pchKey, STEAM_OUT_STRING_COUNT(cchValueSize) char *pchValue, uint32 cchValueSize );
// Some items can specify that they have a version that is valid for a range of game versions (Steam branch)
uint32 GetNumSupportedGameVersions( UGCQueryHandle_t handle, uint32 index ); uint32 GetNumSupportedGameVersions( UGCQueryHandle_t handle, uint32 index );
bool GetSupportedGameVersionData( UGCQueryHandle_t handle, uint32 index, uint32 versionIndex, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMin, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMax, uint32 cchGameBranchSize ); bool GetSupportedGameVersionData( UGCQueryHandle_t handle, uint32 index, uint32 versionIndex, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMin, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMax, uint32 cchGameBranchSize );
@ -172,6 +177,7 @@ public:
bool SetAllowCachedResponse( UGCQueryHandle_t handle, uint32 unMaxAgeSeconds ); bool SetAllowCachedResponse( UGCQueryHandle_t handle, uint32 unMaxAgeSeconds );
// allow ISteamUGC to be used in a tools like environment for users who have the appropriate privileges for the calling appid
bool SetAdminQuery( UGCUpdateHandle_t handle, bool bAdminQuery ); bool SetAdminQuery( UGCUpdateHandle_t handle, bool bAdminQuery );
// Options only for querying user UGC // Options only for querying user UGC

View File

@ -1016,6 +1016,8 @@ static void try_parse_mods_file(class Settings *settings_client, Settings *setti
newMod.previewFileSize = mod.value().value("preview_filesize", preview_filesize); newMod.previewFileSize = mod.value().value("preview_filesize", preview_filesize);
newMod.total_files_sizes = mod.value().value("total_files_sizes", primary_filesize); newMod.total_files_sizes = mod.value().value("total_files_sizes", primary_filesize);
newMod.min_game_branch = mod.value().value("min_game_branch", "");
newMod.max_game_branch = mod.value().value("max_game_branch", "");
newMod.workshopItemURL = mod.value().value("workshop_item_url", "https://steamcommunity.com/sharedfiles/filedetails/?id=" + std::string(mod.key())); newMod.workshopItemURL = mod.value().value("workshop_item_url", "https://steamcommunity.com/sharedfiles/filedetails/?id=" + std::string(mod.key()));
newMod.votesUp = mod.value().value("upvotes", (uint32)500); newMod.votesUp = mod.value().value("upvotes", (uint32)500);
@ -1046,6 +1048,8 @@ static void try_parse_mods_file(class Settings *settings_client, Settings *setti
PRINT_DEBUG(" preview_filesize: %i bytes", newMod.previewFileSize); PRINT_DEBUG(" preview_filesize: %i bytes", newMod.previewFileSize);
PRINT_DEBUG(" preview file handle: %llu", settings_client->getMod(newMod.id).handlePreviewFile); PRINT_DEBUG(" preview file handle: %llu", settings_client->getMod(newMod.id).handlePreviewFile);
PRINT_DEBUG(" total_files_sizes: %llu", settings_client->getMod(newMod.id).total_files_sizes); PRINT_DEBUG(" total_files_sizes: %llu", settings_client->getMod(newMod.id).total_files_sizes);
PRINT_DEBUG(" min_game_branch: '%s'", settings_client->getMod(newMod.id).min_game_branch.c_str());
PRINT_DEBUG(" max_game_branch: '%s'", settings_client->getMod(newMod.id).max_game_branch.c_str());
PRINT_DEBUG(" workshop_item_url: '%s'", newMod.workshopItemURL.c_str()); PRINT_DEBUG(" workshop_item_url: '%s'", newMod.workshopItemURL.c_str());
PRINT_DEBUG(" preview_url: '%s'", newMod.previewURL.c_str()); PRINT_DEBUG(" preview_url: '%s'", newMod.previewURL.c_str());
} catch (std::exception& e) { } catch (std::exception& e) {
@ -1111,6 +1115,8 @@ static void try_detect_mods_folder(class Settings *settings_client, Settings *se
PRINT_DEBUG(" preview_filesize: %i bytes", newMod.previewFileSize); PRINT_DEBUG(" preview_filesize: %i bytes", newMod.previewFileSize);
PRINT_DEBUG(" preview file handle: %llu", settings_client->getMod(newMod.id).handlePreviewFile); PRINT_DEBUG(" preview file handle: %llu", settings_client->getMod(newMod.id).handlePreviewFile);
PRINT_DEBUG(" total_files_sizes: '%s'", newMod.total_files_sizes); PRINT_DEBUG(" total_files_sizes: '%s'", newMod.total_files_sizes);
PRINT_DEBUG(" min_game_branch: '%s'", newMod.min_game_branch.c_str());
PRINT_DEBUG(" max_game_branch: '%s'", newMod.max_game_branch.c_str());
PRINT_DEBUG(" workshop_item_url: '%s'", newMod.workshopItemURL.c_str()); PRINT_DEBUG(" workshop_item_url: '%s'", newMod.workshopItemURL.c_str());
PRINT_DEBUG(" preview_url: '%s'", newMod.previewURL.c_str()); PRINT_DEBUG(" preview_url: '%s'", newMod.previewURL.c_str());
} catch (...) {} } catch (...) {}

View File

@ -106,7 +106,7 @@ void Steam_UGC::set_details(PublishedFileId_t id, SteamUGCDetails_t *pDetails)
// TODO should we enable this? // TODO should we enable this?
// pDetails->m_unNumChildren = mod.numChildren; // pDetails->m_unNumChildren = mod.numChildren;
// TODO make the filesize is good // TODO make sure the filesize is good
pDetails->m_ulTotalFilesSize = mod.total_files_sizes; pDetails->m_ulTotalFilesSize = mod.total_files_sizes;
} else { } else {
PRINT_DEBUG(" mod isn't installed, returning failure"); PRINT_DEBUG(" mod isn't installed, returning failure");
@ -364,8 +364,9 @@ bool Steam_UGC::GetQueryUGCPreviewURL( UGCQueryHandle_t handle, uint32 index, ST
auto res = get_query_ugc(handle, index); auto res = get_query_ugc(handle, index);
if (!res.has_value()) return false; if (!res.has_value()) return false;
auto mod = res.value(); auto &mod = res.value();
PRINT_DEBUG("Steam_UGC:GetQueryUGCPreviewURL: '%s'", mod.previewURL.c_str()); PRINT_DEBUG("Steam_UGC:GetQueryUGCPreviewURL: '%s'", mod.previewURL.c_str());
memset(pchURL, 0, cchURLSize);
mod.previewURL.copy(pchURL, cchURLSize - 1); mod.previewURL.copy(pchURL, cchURLSize - 1);
return true; return true;
} }
@ -495,29 +496,47 @@ bool Steam_UGC::GetQueryUGCKeyValueTag( UGCQueryHandle_t handle, uint32 index, c
return false; return false;
} }
// TODO no public docs
// Some items can specify that they have a version that is valid for a range of game versions (Steam branch)
uint32 Steam_UGC::GetNumSupportedGameVersions( UGCQueryHandle_t handle, uint32 index ) uint32 Steam_UGC::GetNumSupportedGameVersions( UGCQueryHandle_t handle, uint32 index )
{ {
PRINT_DEBUG_TODO(); PRINT_DEBUG("%llu %u // TODO", handle, index);
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
if (handle == k_UGCQueryHandleInvalid) return 0; if (handle == k_UGCQueryHandleInvalid) return 0;
auto request = std::find_if(ugc_queries.begin(), ugc_queries.end(), [&handle](struct UGC_query const& item) { return item.handle == handle; }); auto res = get_query_ugc(handle, index);
if (ugc_queries.end() == request) return 0; if (!res.has_value()) return 0;
return 1; return 1;
} }
// TODO no public docs
bool Steam_UGC::GetSupportedGameVersionData( UGCQueryHandle_t handle, uint32 index, uint32 versionIndex, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMin, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMax, uint32 cchGameBranchSize ) bool Steam_UGC::GetSupportedGameVersionData( UGCQueryHandle_t handle, uint32 index, uint32 versionIndex, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMin, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMax, uint32 cchGameBranchSize )
{ {
PRINT_DEBUG_TODO(); PRINT_DEBUG("%llu %u %u // TODO", handle, index, versionIndex);
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
if (handle == k_UGCQueryHandleInvalid) return false; if (handle == k_UGCQueryHandleInvalid) return false;
if (index != 0) return false; // TODO ??
auto request = std::find_if(ugc_queries.begin(), ugc_queries.end(), [&handle](struct UGC_query const& item) { return item.handle == handle; }); if (versionIndex != 0) { // TODO I assume this is supposed to be an index in the range [ 0, GetNumSupportedGameVersions() )
if (ugc_queries.end() == request) return false; return false;
}
return false; // TODO ?? auto res = get_query_ugc(handle, index);
if (!res.has_value()) return false;
auto &mod = res.value();
// TODO I assume each mod/workshop item has a min version and max version for the game
if (pchGameBranchMin && static_cast<size_t>(cchGameBranchSize) > mod.min_game_branch.size()) {
memset(pchGameBranchMin, 0, cchGameBranchSize);
memcpy(pchGameBranchMin, mod.min_game_branch.c_str(), mod.min_game_branch.size());
}
if (pchGameBranchMax && static_cast<size_t>(cchGameBranchSize) > mod.max_game_branch.size()) {
memset(pchGameBranchMax, 0, cchGameBranchSize);
memcpy(pchGameBranchMax, mod.max_game_branch.c_str(), mod.max_game_branch.size());
}
return true;
} }
uint32 Steam_UGC::GetQueryUGCContentDescriptors( UGCQueryHandle_t handle, uint32 index, EUGCContentDescriptorID *pvecDescriptors, uint32 cMaxEntries ) uint32 Steam_UGC::GetQueryUGCContentDescriptors( UGCQueryHandle_t handle, uint32 index, EUGCContentDescriptorID *pvecDescriptors, uint32 cMaxEntries )
@ -526,8 +545,8 @@ uint32 Steam_UGC::GetQueryUGCContentDescriptors( UGCQueryHandle_t handle, uint32
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
if (handle == k_UGCQueryHandleInvalid) return 0; if (handle == k_UGCQueryHandleInvalid) return 0;
auto request = std::find_if(ugc_queries.begin(), ugc_queries.end(), [&handle](struct UGC_query const& item) { return item.handle == handle; }); auto res = get_query_ugc(handle, index);
if (ugc_queries.end() == request) return 0; if (!res.has_value()) return 0;
return 0; return 0;
} }
@ -712,15 +731,18 @@ bool Steam_UGC::SetAllowCachedResponse( UGCQueryHandle_t handle, uint32 unMaxAge
return true; return true;
} }
// TODO no public docs
// allow ISteamUGC to be used in a tools like environment for users who have the appropriate privileges for the calling appid
bool Steam_UGC::SetAdminQuery( UGCUpdateHandle_t handle, bool bAdminQuery ) bool Steam_UGC::SetAdminQuery( UGCUpdateHandle_t handle, bool bAdminQuery )
{ {
PRINT_DEBUG_TODO(); PRINT_DEBUG("%llu %i // TODO", handle, (int)bAdminQuery);
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
if (handle == k_UGCQueryHandleInvalid) return false; if (handle == k_UGCQueryHandleInvalid) return false;
auto request = std::find_if(ugc_queries.begin(), ugc_queries.end(), [&handle](struct UGC_query const& item) { return item.handle == handle; }); auto request = std::find_if(ugc_queries.begin(), ugc_queries.end(), [&handle](struct UGC_query const& item) { return item.handle == handle; });
if (ugc_queries.end() == request) return false; if (ugc_queries.end() == request) return false;
request->admin_query = bAdminQuery;
return true; return true;
} }
@ -1046,6 +1068,7 @@ bool Steam_UGC::RemoveContentDescriptor( UGCUpdateHandle_t handle, EUGCContentDe
return false; return false;
} }
// TODO no public docs
bool Steam_UGC::SetRequiredGameVersions( UGCUpdateHandle_t handle, const char *pszGameBranchMin, const char *pszGameBranchMax ) bool Steam_UGC::SetRequiredGameVersions( UGCUpdateHandle_t handle, const char *pszGameBranchMin, const char *pszGameBranchMax )
{ {
PRINT_DEBUG("%llu '%s' '%s' // TODO", handle, pszGameBranchMin, pszGameBranchMax); PRINT_DEBUG("%llu '%s' '%s' // TODO", handle, pszGameBranchMin, pszGameBranchMax);
@ -1056,7 +1079,9 @@ bool Steam_UGC::SetRequiredGameVersions( UGCUpdateHandle_t handle, const char *p
auto request = std::find_if(ugc_queries.begin(), ugc_queries.end(), [&handle](struct UGC_query const& item) { return item.handle == handle; }); auto request = std::find_if(ugc_queries.begin(), ugc_queries.end(), [&handle](struct UGC_query const& item) { return item.handle == handle; });
if (ugc_queries.end() == request) return false; if (ugc_queries.end() == request) return false;
return false; if (pszGameBranchMin) request->min_branch = pszGameBranchMin;
if (pszGameBranchMax) request->max_branch = pszGameBranchMax;
return true;
} }
STEAM_CALL_RESULT( SubmitItemUpdateResult_t ) STEAM_CALL_RESULT( SubmitItemUpdateResult_t )

View File

@ -19,6 +19,8 @@
"preview_filename": "test.png", "preview_filename": "test.png",
"preview_filesize": 1000000, "preview_filesize": 1000000,
"total_files_sizes": 9977664411, "total_files_sizes": 9977664411,
"min_game_branch": "1.4.2",
"max_game_branch": "1.5.0",
"workshop_item_url": "https://steamcommunity.com/sharedfiles/filedetails/?id=111111111", "workshop_item_url": "https://steamcommunity.com/sharedfiles/filedetails/?id=111111111",
"upvotes": 10, "upvotes": 10,
"downvotes": 1, "downvotes": 1,

View File

@ -249,9 +249,9 @@ public:
STEAM_FLAT_NAME( GetQueryFirstUGCKeyValueTag ) STEAM_FLAT_NAME( GetQueryFirstUGCKeyValueTag )
virtual bool GetQueryUGCKeyValueTag( UGCQueryHandle_t handle, uint32 index, const char *pchKey, STEAM_OUT_STRING_COUNT(cchValueSize) char *pchValue, uint32 cchValueSize ) = 0; virtual bool GetQueryUGCKeyValueTag( UGCQueryHandle_t handle, uint32 index, const char *pchKey, STEAM_OUT_STRING_COUNT(cchValueSize) char *pchValue, uint32 cchValueSize ) = 0;
// Some items can specify that they have a version that is valid for a range of game versions (Steam branch) // Some items can specify that they have a version that is valid for a range of game versions (Steam branch)
virtual uint32 GetNumSupportedGameVersions( UGCQueryHandle_t handle, uint32 index ) = 0; virtual uint32 GetNumSupportedGameVersions( UGCQueryHandle_t handle, uint32 index ) = 0;
virtual bool GetSupportedGameVersionData( UGCQueryHandle_t handle, uint32 index, uint32 versionIndex, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMin, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMax, uint32 cchGameBranchSize ) = 0; virtual bool GetSupportedGameVersionData( UGCQueryHandle_t handle, uint32 index, uint32 versionIndex, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMin, STEAM_OUT_STRING_COUNT( cchGameBranchSize ) char *pchGameBranchMax, uint32 cchGameBranchSize ) = 0;
virtual uint32 GetQueryUGCContentDescriptors( UGCQueryHandle_t handle, uint32 index, EUGCContentDescriptorID *pvecDescriptors, uint32 cMaxEntries ) = 0; virtual uint32 GetQueryUGCContentDescriptors( UGCQueryHandle_t handle, uint32 index, EUGCContentDescriptorID *pvecDescriptors, uint32 cMaxEntries ) = 0;
@ -273,6 +273,7 @@ public:
virtual bool SetReturnPlaytimeStats( UGCQueryHandle_t handle, uint32 unDays ) = 0; virtual bool SetReturnPlaytimeStats( UGCQueryHandle_t handle, uint32 unDays ) = 0;
virtual bool SetLanguage( UGCQueryHandle_t handle, const char *pchLanguage ) = 0; virtual bool SetLanguage( UGCQueryHandle_t handle, const char *pchLanguage ) = 0;
virtual bool SetAllowCachedResponse( UGCQueryHandle_t handle, uint32 unMaxAgeSeconds ) = 0; virtual bool SetAllowCachedResponse( UGCQueryHandle_t handle, uint32 unMaxAgeSeconds ) = 0;
// allow ISteamUGC to be used in a tools like environment for users who have the appropriate privileges for the calling appid
virtual bool SetAdminQuery( UGCUpdateHandle_t handle, bool bAdminQuery ) = 0; // admin queries return hidden items virtual bool SetAdminQuery( UGCUpdateHandle_t handle, bool bAdminQuery ) = 0; // admin queries return hidden items
// Options only for querying user UGC // Options only for querying user UGC