-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Workshop mods are broken in HL2 #98
Comments
I don't know man, I'm tired of this project. |
:(
Oh yes, forgot to set that one, but sadly no change.
Only lines with "primary" are the try_parse_mods_file one. |
Uploading isnt written (As far as I remember) |
It's just that I expect "Content Folder" to be filled with path to mod, just like title, description or preview image get filled. I obviously expect all social features to not be implemented but that not important. I also tested a Windows build and it's the same behavior, no preview image without implementing GetUGCDetails and broken mods whether that function get implemented or not. The only difference is that for some reason, I can edit mod that aren't my own on Linux, but on Windows, I only see those that have steam_id_owner set to my own. |
Found the problem ding ding ding! Notice both {
"3366485326": {
"steam_id_owner": 76561198139810670,
"path": "C:\\Program Files (x86)\\Steam\\steamapps\\workshop\\content\\220\\3366485326",
"title": "GoldSource GUI [HL2]",
"tags": "assets,materials,ui",
"total_files_sizes": 43663,
"primary_filesize": 43663,
"description": "Old Steam/GoldSource styled GUI",
"primary_filename": "workshop_dir.vpk",
"preview_filename": "download.png"
}
} Found this by creating a dump of the actual returned data from real steamclient64.dll. I'd recommend initializing the function params before doing any checks PRINT_DEBUG("%llu // TODO", hContent);
std::lock_guard<std::recursive_mutex> lock(global_mutex);
if (pnAppID) *pnAppID = settings->get_local_game_id().AppID();
if (pSteamIDOwner) *pSteamIDOwner = k_steamIDNil;
if (pnFileSizeInBytes) *pnFileSizeInBytes = 0;
if (ppchName) *ppchName = nullptr;
...
... Many games don't even care about the return of the function, only their own buffers (since in real scenario Steam won't fail but here we can fail since the emulation might not always be accurate). ...
...
if (ppchName) {
*ppchName = new char[mod_name.size() + 1];
std::strcpy(*ppchName, mod_name.c_str());
}
if (pnFileSizeInBytes) *pnFileSizeInBytes = mod_size;
if (pSteamIDOwner) *pSteamIDOwner = mod.steamIDOwner;
Fun trivia:
|
Nice!
So it got that info from
Will apply these fixes and open a PR if everything is working correctly. Why the TODO in print? I noticed a lot of TODO in functions that seemed to be fully implemented.
I don't really understand all that trivia, but I guess it's a bit special because it's basically compressed; workshop_dir.vpk and workshop_xxx.vpk is the same archive split in multiple files. |
Not sure about that function it's confusing since other games work without doing this manual modification (Human Fall Flat for example). Needs testing by dumping the data from many other games :/ |
I sadly still can't get it to work: {
"3366485326": {
"steam_id_owner": 76561198139810670,
"title": "GoldSource GUI [HL2]",
"tags": "assets,materials,ui",
"total_files_sizes": 43663,
"primary_filesize": 43663,
"description": "Old Steam/GoldSource styled GUI",
"primary_filename": "workshop_dir.vpk",
"preview_filename": "preview_image.jpg"
}
} I verified, my files are exactly 43663 bytes. I even tried putting mods in steam path and specifying it. Also tried on Windows build (without trying steam path in that case). Using latest master (30f1f56) with this patch: diff --git a/dll/steam_remote_storage.cpp b/dll/steam_remote_storage.cpp
index 7ab28fbf..d8541f15 100644
--- a/dll/steam_remote_storage.cpp
+++ b/dll/steam_remote_storage.cpp
@@ -495,9 +495,34 @@ bool Steam_Remote_Storage::GetUGCDownloadProgress( UGCHandle_t hContent, uint32
// Gets metadata for a file after it has been downloaded. This is the same metadata given in the RemoteStorageDownloadUGCResult_t call result
bool Steam_Remote_Storage::GetUGCDetails( UGCHandle_t hContent, AppId_t *pnAppID, STEAM_OUT_STRING() char **ppchName, int32 *pnFileSizeInBytes, STEAM_OUT_STRUCT() CSteamID *pSteamIDOwner )
{
- PRINT_DEBUG_ENTRY();
+ PRINT_DEBUG("%llu", hContent);
std::lock_guard<std::recursive_mutex> lock(global_mutex);
-
+ if (hContent == k_UGCHandleInvalid) return k_uAPICallInvalid;
+
+ if (pnAppID) *pnAppID = settings->get_local_game_id().AppID();
+ if (pSteamIDOwner) *pSteamIDOwner = k_steamIDNil;
+ if (pnFileSizeInBytes) *pnFileSizeInBytes = 0;
+ if (ppchName) *ppchName = nullptr;
+
+ if (auto query_res = ugc_bridge->get_ugc_query_result(hContent)) {
+ auto mod = settings->getMod(query_res.value().mod_id);
+ auto &mod_name = query_res.value().is_primary_file
+ ? mod.primaryFileName
+ : mod.previewFileName;
+ int32 mod_size = query_res.value().is_primary_file
+ ? mod.primaryFileSize
+ : mod.previewFileSize;
+
+ if (ppchName) {
+ *ppchName = new char[mod_name.size() + 1];
+ std::strcpy(*ppchName, mod_name.c_str());
+ }
+ if (pnFileSizeInBytes) *pnFileSizeInBytes = mod_size;
+ if (pSteamIDOwner) *pSteamIDOwner = mod.steamIDOwner;
+
+ return true;
+ }
+
return false;
}
|
BTW, don't use |
That wouldn't even compile. It's the job of the caller to manage that string and free its memory. |
Apologies for forgetting type conversion there, it should be |
@Edremon I forgot to push a damn fix for querying tags count in @universal963 You are right, we can create a simple hash map or something as a strong reference storage, but laziness is king 😄 |
"3366485326": {
"title": "GoldSource GUI [HL2]",
"tags": "assets,materials,ui",
"primary_filesize": 43663,
"preview_filename": "preview_image.jpg"
} As for best way to implement |
Indeed that string might be destroyed at some point but it should be noted that:
|
Seems like HL2 want "type" tag or it put stuff as broken. Made a small script to generate a mods.json from mod directory using ISteamRemoteStorage/GetPublishedFileDetails web API (doesn't require API key), allow populating title, description, steam_id_owner, time_created, time_updated, tags, primary_filesize and preview_filename (that get downloaded). |
Fixed with #103, #104 and #106. Here a small script to create mods settings from a |
I'm trying to add mods to HL2, in the current emulator state, the mod doesn't load correctly and show as "Broken Item!" in the workshop menu, the preview image is also not shown.
In HL2 logs, we get
[CWorkshopImage] GetUGCDetails failed? (UGC=0000000000000004 nFileSizeInBytes=-1).
this function wasn't implemented, I implemented it like so:Preview image is now shown, but I still get "Broken Item!" and mod is not working.
I tried multiple mods, all have the same problem. Here mods.json on that example:
Mods directory structure:
I tried filling all the json data, debug have nothing interesting in it, below are all related lines to workshop or UGC.
Logs
The text was updated successfully, but these errors were encountered: