mirror of
https://github.com/Detanup01/gbe_fork.git
synced 2025-01-07 16:24:15 +08:00
Merge pull request #103 from otavepto/patch-mods-access-tags-count-fix
another fix for accessing mod details struct + querying tags count
This commit is contained in:
commit
5ec0435a45
@ -82,7 +82,7 @@ private:
|
||||
|
||||
std::optional<std::string> get_query_ugc_tag(UGCQueryHandle_t handle, uint32 index, uint32 indexTag);
|
||||
|
||||
std::optional<std::vector<std::string>> get_query_ugc_tags(UGCQueryHandle_t handle, uint32 index);
|
||||
std::vector<std::string> get_query_ugc_tags(UGCQueryHandle_t handle, uint32 index);
|
||||
|
||||
void set_details(PublishedFileId_t id, SteamUGCDetails_t *pDetails, IUgcItfVersion ver);
|
||||
|
||||
|
@ -220,6 +220,8 @@ void Settings::addModDetails(PublishedFileId_t id, const Mod_entry &details)
|
||||
f->numChildren = details.numChildren;
|
||||
f->previewURL = details.previewURL;
|
||||
f->total_files_sizes = details.total_files_sizes;
|
||||
f->min_game_branch = details.min_game_branch;
|
||||
f->max_game_branch = details.max_game_branch;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -940,6 +940,12 @@ static void parse_installed_app_Ids(class Settings *settings_client, class Setti
|
||||
static const auto one_week_ago_epoch = std::chrono::duration_cast<std::chrono::seconds>(
|
||||
( startup_time - std::chrono::hours(24 * 7) ).time_since_epoch()
|
||||
).count();
|
||||
static const auto two_week_ago_epoch = std::chrono::duration_cast<std::chrono::seconds>(
|
||||
( startup_time - std::chrono::hours(24 * 7 * 2) ).time_since_epoch()
|
||||
).count();
|
||||
static const auto three_week_ago_epoch = std::chrono::duration_cast<std::chrono::seconds>(
|
||||
( startup_time - std::chrono::hours(24 * 7 * 3) ).time_since_epoch()
|
||||
).count();
|
||||
|
||||
static size_t get_file_size_safe(const std::string &filepath, const std::string &basepath, int32 default_val = 0)
|
||||
{
|
||||
@ -963,7 +969,16 @@ static std::string get_mod_preview_url(const std::string &previewFileName, const
|
||||
} else {
|
||||
auto settings_folder = std::string(Local_Storage::get_game_settings_path());
|
||||
std::replace(settings_folder.begin(), settings_folder.end(), '\\', '/');
|
||||
return "file://" + settings_folder + "mod_images/" + mod_id + "/" + previewFileName;
|
||||
|
||||
return
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
"file:///"
|
||||
#else // on Linux absolute paths start like this: /my/path, so the 3rd slash is already appended
|
||||
"file://"
|
||||
#endif
|
||||
|
||||
+ settings_folder + "mod_images/" + mod_id + "/" + previewFileName;
|
||||
}
|
||||
|
||||
}
|
||||
@ -992,8 +1007,8 @@ static void try_parse_mods_file(class Settings *settings_client, Settings *setti
|
||||
newMod.fileType = k_EWorkshopFileTypeCommunity;
|
||||
newMod.description = mod.value().value("description", std::string(""));
|
||||
newMod.steamIDOwner = mod.value().value("steam_id_owner", settings_client->get_local_steam_id().ConvertToUint64());
|
||||
newMod.timeCreated = mod.value().value("time_created", (uint32)one_week_ago_epoch);
|
||||
newMod.timeUpdated = mod.value().value("time_updated", (uint32)one_week_ago_epoch);
|
||||
newMod.timeCreated = mod.value().value("time_created", (uint32)three_week_ago_epoch);
|
||||
newMod.timeUpdated = mod.value().value("time_updated", (uint32)two_week_ago_epoch);
|
||||
newMod.timeAddedToUserList = mod.value().value("time_added", (uint32)one_week_ago_epoch);
|
||||
newMod.visibility = k_ERemoteStoragePublishedFileVisibilityPublic;
|
||||
newMod.banned = false;
|
||||
@ -1076,8 +1091,8 @@ static void try_detect_mods_folder(class Settings *settings_client, Settings *se
|
||||
newMod.fileType = k_EWorkshopFileTypeCommunity;
|
||||
newMod.description = "mod #" + mod_folder;
|
||||
newMod.steamIDOwner = settings_client->get_local_steam_id().ConvertToUint64();
|
||||
newMod.timeCreated = (uint32)one_week_ago_epoch;
|
||||
newMod.timeUpdated = (uint32)one_week_ago_epoch;
|
||||
newMod.timeCreated = (uint32)three_week_ago_epoch;
|
||||
newMod.timeUpdated = (uint32)two_week_ago_epoch;
|
||||
newMod.timeAddedToUserList = (uint32)one_week_ago_epoch;
|
||||
newMod.visibility = k_ERemoteStoragePublishedFileVisibilityPublic;
|
||||
newMod.banned = false;
|
||||
|
@ -446,7 +446,6 @@ SteamAPICall_t Steam_Remote_Storage::UGCDownload( UGCHandle_t hContent, uint32 u
|
||||
data.m_eResult = k_EResultOK;
|
||||
data.m_ulSteamIDOwner = mod.steamIDOwner;
|
||||
data.m_nSizeInBytes = mod_size;
|
||||
data.m_ulSteamIDOwner = mod.steamIDOwner;
|
||||
|
||||
mod_name.copy(data.m_pchFileName, sizeof(data.m_pchFileName) - 1);
|
||||
PRINT_DEBUG(" QueryUGCRequest data.m_pchFileName = '%s'", data.m_pchFileName);
|
||||
@ -1157,7 +1156,6 @@ SteamAPICall_t Steam_Remote_Storage::UGCDownloadToLocation( UGCHandle_t hContent
|
||||
data.m_nAppID = settings->get_local_game_id().AppID();
|
||||
data.m_ulSteamIDOwner = mod.steamIDOwner;
|
||||
data.m_nSizeInBytes = mod_size;
|
||||
data.m_ulSteamIDOwner = mod.steamIDOwner;
|
||||
|
||||
mod_name.copy(data.m_pchFileName, sizeof(data.m_pchFileName) - 1);
|
||||
|
||||
|
@ -48,19 +48,25 @@ std::optional<Mod_entry> Steam_UGC::get_query_ugc(UGCQueryHandle_t handle, uint3
|
||||
return settings->getMod(file_id);
|
||||
}
|
||||
|
||||
std::optional<std::vector<std::string>> Steam_UGC::get_query_ugc_tags(UGCQueryHandle_t handle, uint32 index)
|
||||
std::vector<std::string> Steam_UGC::get_query_ugc_tags(UGCQueryHandle_t handle, uint32 index)
|
||||
{
|
||||
auto res = get_query_ugc(handle, index);
|
||||
if (!res.has_value()) return std::nullopt;
|
||||
if (!res.has_value()) return {};
|
||||
|
||||
std::string tmp = res.value().tags;
|
||||
|
||||
auto tags_tokens = std::vector<std::string>{};
|
||||
std::stringstream ss(res.value().tags);
|
||||
std::string tmp{};
|
||||
while(ss >> tmp) {
|
||||
if (tmp.back() == ',') tmp = tmp.substr(0, tmp.size() - 1);
|
||||
tags_tokens.push_back(tmp);
|
||||
size_t start = 0;
|
||||
while (true) {
|
||||
auto end = tmp.find(',', start);
|
||||
if (end == std::string::npos) break;
|
||||
|
||||
tags_tokens.push_back(tmp.substr(start, end - start));
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
tags_tokens.push_back(tmp.substr(start));
|
||||
|
||||
return tags_tokens;
|
||||
|
||||
}
|
||||
@ -68,8 +74,6 @@ std::optional<std::vector<std::string>> Steam_UGC::get_query_ugc_tags(UGCQueryHa
|
||||
void Steam_UGC::set_details(PublishedFileId_t id, SteamUGCDetails_t *pDetails, IUgcItfVersion ver)
|
||||
{
|
||||
if (pDetails) {
|
||||
memset(pDetails, 0, sizeof(SteamUGCDetails_t));
|
||||
|
||||
pDetails->m_nPublishedFileId = id;
|
||||
|
||||
if (settings->isModInstalled(id)) {
|
||||
@ -90,18 +94,29 @@ void Steam_UGC::set_details(PublishedFileId_t id, SteamUGCDetails_t *pDetails, I
|
||||
pDetails->m_nPreviewFileSize = mod.previewFileSize;
|
||||
pDetails->m_rtimeCreated = mod.timeCreated;
|
||||
pDetails->m_rtimeUpdated = mod.timeUpdated;
|
||||
pDetails->m_ulSteamIDOwner = settings->get_local_steam_id().ConvertToUint64();
|
||||
pDetails->m_ulSteamIDOwner = mod.steamIDOwner;
|
||||
|
||||
pDetails->m_rtimeAddedToUserList = mod.timeAddedToUserList;
|
||||
pDetails->m_unVotesUp = mod.votesUp;
|
||||
pDetails->m_unVotesDown = mod.votesDown;
|
||||
pDetails->m_flScore = mod.score;
|
||||
|
||||
mod.primaryFileName.copy(pDetails->m_pchFileName, sizeof(pDetails->m_pchFileName) - 1);
|
||||
mod.description.copy(pDetails->m_rgchDescription, sizeof(pDetails->m_rgchDescription) - 1);
|
||||
mod.tags.copy(pDetails->m_rgchTags, sizeof(pDetails->m_rgchTags) - 1);
|
||||
mod.title.copy(pDetails->m_rgchTitle, sizeof(pDetails->m_rgchTitle) - 1);
|
||||
mod.workshopItemURL.copy(pDetails->m_rgchURL, sizeof(pDetails->m_rgchURL) - 1);
|
||||
// real steamclient64.dll may set this to null! (ex: item id 3366485326)
|
||||
auto copied_chars = mod.primaryFileName.copy(pDetails->m_pchFileName, sizeof(pDetails->m_pchFileName) - 1);
|
||||
pDetails->m_pchFileName[copied_chars] = 0;
|
||||
|
||||
copied_chars = mod.description.copy(pDetails->m_rgchDescription, sizeof(pDetails->m_rgchDescription) - 1);
|
||||
pDetails->m_rgchDescription[copied_chars] = 0;
|
||||
|
||||
copied_chars = mod.tags.copy(pDetails->m_rgchTags, sizeof(pDetails->m_rgchTags) - 1);
|
||||
pDetails->m_rgchTags[copied_chars] = 0;
|
||||
|
||||
copied_chars = mod.title.copy(pDetails->m_rgchTitle, sizeof(pDetails->m_rgchTitle) - 1);
|
||||
pDetails->m_rgchTitle[copied_chars] = 0;
|
||||
|
||||
// real steamclient64.dll may set this to null! (ex: item id 3366485326)
|
||||
copied_chars = mod.workshopItemURL.copy(pDetails->m_rgchURL, sizeof(pDetails->m_rgchURL) - 1);
|
||||
pDetails->m_rgchURL[copied_chars] = 0;
|
||||
|
||||
// TODO should we enable this?
|
||||
// pDetails->m_unNumChildren = mod.numChildren;
|
||||
@ -362,11 +377,11 @@ bool Steam_UGC::GetQueryUGCResult_old( UGCQueryHandle_t handle, uint32 index, St
|
||||
std::optional<std::string> Steam_UGC::get_query_ugc_tag(UGCQueryHandle_t handle, uint32 index, uint32 indexTag)
|
||||
{
|
||||
auto res = get_query_ugc_tags(handle, index);
|
||||
if (!res.has_value()) return std::nullopt;
|
||||
if (indexTag >= res.value().size()) return std::nullopt;
|
||||
if (res.empty()) return std::nullopt;
|
||||
if (indexTag >= res.size()) return std::nullopt;
|
||||
|
||||
std::string tmp = res.value()[indexTag];
|
||||
if (tmp.back() == ',') {
|
||||
std::string tmp = res[indexTag];
|
||||
if (!tmp.empty() && tmp.back() == ',') {
|
||||
tmp = tmp.substr(0, tmp.size() - 1);
|
||||
}
|
||||
return tmp;
|
||||
@ -380,7 +395,7 @@ uint32 Steam_UGC::GetQueryUGCNumTags( UGCQueryHandle_t handle, uint32 index )
|
||||
if (handle == k_UGCQueryHandleInvalid) return 0;
|
||||
|
||||
auto res = get_query_ugc_tags(handle, index);
|
||||
return res.has_value() ? static_cast<uint32>(res.value().size()) : 0;
|
||||
return static_cast<uint32>(res.size());
|
||||
}
|
||||
|
||||
bool Steam_UGC::GetQueryUGCTag( UGCQueryHandle_t handle, uint32 index, uint32 indexTag, STEAM_OUT_STRING_COUNT( cchValueSize ) char* pchValue, uint32 cchValueSize )
|
||||
@ -994,9 +1009,7 @@ bool Steam_UGC::SetItemVisibility( UGCUpdateHandle_t handle, ERemoteStoragePubli
|
||||
bool Steam_UGC::SetItemTags( UGCUpdateHandle_t updateHandle, const SteamParamStringArray_t *pTags )
|
||||
{
|
||||
PRINT_DEBUG("old");
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
return false;
|
||||
return SetItemTags(updateHandle, pTags, false);
|
||||
}
|
||||
|
||||
bool Steam_UGC::SetItemTags( UGCUpdateHandle_t updateHandle, const SteamParamStringArray_t *pTags, bool bAllowAdminTags )
|
||||
@ -1368,7 +1381,7 @@ bool Steam_UGC::GetItemInstallInfo( PublishedFileId_t nPublishedFileID, uint64 *
|
||||
}
|
||||
|
||||
if (punSizeOnDisk) *punSizeOnDisk = mod.primaryFileSize;
|
||||
if (punTimeStamp) *punTimeStamp = mod.timeUpdated;
|
||||
if (punTimeStamp) *punTimeStamp = mod.timeAddedToUserList;
|
||||
if (pchFolder && cchFolderSize) {
|
||||
// human fall flat doesn't send a nulled buffer, and won't recognize the proper mod path because of that
|
||||
memset(pchFolder, 0, cchFolderSize);
|
||||
|
@ -82,3 +82,14 @@ This dll is meant to be injected during **startup** only, it must **not** be pla
|
||||
## `GameOverlayRenderer`
|
||||
Some apps verify the existence of this dll, either on disk, or inside their memory space, that's why this dll exists.
|
||||
It is **NOT** recommended to ignore this dll.
|
||||
|
||||
## Mods paths (source-engine games on Windows)
|
||||
On Windows, the registry key `SourceModInstallPath` is changed to the folder containing the loader.
|
||||
```
|
||||
Registry path: HKEY_CURRENT_USER\SOFTWARE\Valve\Steam
|
||||
Registry key: SourceModInstallPath
|
||||
Original value: C:\Program Files (x86)\Steam\steamapps\sourcemods
|
||||
New value: <FOLDER CONTAINING THE LOADER>
|
||||
```
|
||||
|
||||
This affects source-engine mods
|
||||
|
@ -1,51 +1,51 @@
|
||||
{
|
||||
"9422": {
|
||||
"title": "Some Workshop Item",
|
||||
"description": "This is the prefered way of specifying mod details, primary file must exist in steam_settings/mods/9422 (along with any other mod files), and preview file must exist in steam_settings/mod_images/9422",
|
||||
"primary_filename": "metadata.json",
|
||||
"preview_filename": "thumbnail.png"
|
||||
},
|
||||
"9422": {
|
||||
"title": "Some Workshop Item",
|
||||
"description": "This is the prefered way of specifying mod details, primary file must exist in steam_settings/mods/9422 (along with any other mod files), and preview file must exist in steam_settings/mod_images/9422",
|
||||
"primary_filename": "metadata.json",
|
||||
"preview_filename": "thumbnail.png"
|
||||
},
|
||||
|
||||
"111111111": {
|
||||
"title": "Example Workshop Item",
|
||||
"description": "Example Workshop Item with all Details",
|
||||
"steam_id_owner": 11111111111111111,
|
||||
"time_created": 1554997000,
|
||||
"time_updated": 1554997000,
|
||||
"time_added": 1554997000,
|
||||
"tags": "Maps, exampleTag, exampleTag2",
|
||||
"primary_filename": "test.sav",
|
||||
"primary_filesize": 1000000,
|
||||
"preview_filename": "test.png",
|
||||
"preview_filesize": 1000000,
|
||||
"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",
|
||||
"upvotes": 10,
|
||||
"downvotes": 1,
|
||||
"num_children": 0,
|
||||
"path": "C:\\games\\my_game\\steam_settings\\mods_data\\mod_111111111_data_folder",
|
||||
"preview_url": "file://C:/games/my_game/steam_settings/mod_images/my_preview.jpg",
|
||||
"score": 0.7
|
||||
},
|
||||
|
||||
"222222222": {
|
||||
"title": "Example Workshop Item",
|
||||
"description": "Example Workshop Item with some Details",
|
||||
"preview_url": "https://commons.wikimedia.org/wiki/File:Tree_in_Mississippi.jpg",
|
||||
"score": 1.0
|
||||
},
|
||||
|
||||
"333333333": {
|
||||
"title": "Example Workshop Item"
|
||||
},
|
||||
|
||||
"444444444": {
|
||||
"title": "Example Workshop Item",
|
||||
"description": "Example Workshop Item"
|
||||
},
|
||||
|
||||
"555555555": {
|
||||
}
|
||||
"111111111": {
|
||||
"title": "Example Workshop Item",
|
||||
"description": "Example Workshop Item with all Details",
|
||||
"steam_id_owner": 11111111111111111,
|
||||
"time_created": 1554997000,
|
||||
"time_updated": 1554997000,
|
||||
"time_added": 1554997000,
|
||||
"tags": "Maps,exampleTag,exampleTag2",
|
||||
"primary_filename": "test.sav",
|
||||
"primary_filesize": 1000000,
|
||||
"preview_filename": "test.png",
|
||||
"preview_filesize": 1000000,
|
||||
"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",
|
||||
"upvotes": 10,
|
||||
"downvotes": 1,
|
||||
"num_children": 0,
|
||||
"path": "C:\\games\\my_game\\steam_settings\\mods_data\\mod_111111111_data_folder",
|
||||
"preview_url": "file:///C:/games/my_game/steam_settings/mod_images/my_preview.jpg",
|
||||
"score": 0.7
|
||||
},
|
||||
|
||||
"222222222": {
|
||||
"title": "Example Workshop Item",
|
||||
"description": "Example Workshop Item with some Details",
|
||||
"preview_url": "https://commons.wikimedia.org/wiki/File:Tree_in_Mississippi.jpg",
|
||||
"score": 1.0
|
||||
},
|
||||
|
||||
"333333333": {
|
||||
"title": "Example Workshop Item"
|
||||
},
|
||||
|
||||
"444444444": {
|
||||
"title": "Example Workshop Item",
|
||||
"description": "Example Workshop Item"
|
||||
},
|
||||
|
||||
"555555555": {
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user