tralph3 / Steam-Metadata-Editor

An easy to use GUI that edits the metadata of your Steam Apps
GNU General Public License v3.0
161 stars 18 forks source link

shortcuts.vdf compatibility #40

Open parkerlreed opened 8 months ago

parkerlreed commented 8 months ago

Would be great to manage non Steam shortcuts as well

Steam/userdata/43121766/config/shortcuts.vdf

I tried as a drop in replacement in the code for appinfo.vdf but SME throws an error about invalid VDF version

tralph3 commented 8 months ago

What usecase would this cover? Since shortcuts can already be modified inside Steam's UI, what's the point of doing it via SME? Unless there's some setting you can tweak in that file that can't be done through Steam, I fail to see the utility of this.

sonic2kk commented 8 months ago

Just poking my nose in: Bulk-editing shortcuts (perhaps also adding them to collections/new collections?) is one potential use-case. It could also be useful for mass deleting shortcuts. ProtonUp-Qt has a shortcut editor and I use it to delete shortcuts.

One part that Steam doesn't let you edit for Non-Steam Games is the AppID. This can be modified to be anything so long as it fits the format Steam expects (that's how programs like Steam-ROM-Manager and SteamTinkerLaunch add shortcuts and can set artwork, as they have a known AppID ahead of time). It may be useful to be able to edit this, but I think this is a very niche use-case :-) It could also be useful to display the other AppID formats, such as the unsigned 32bit integer and the hex AppID straight from the shortcuts.vdf file. Also displaying the total number of shortcuts could be useful to know. SME could also allow for bulk-updating the compatibility tool used for shortcuts, though this would only be applicable to Linux.

Editing the AppID could be risky if a user doesn't know what they're doing, as on Linux it will create a new compatdata if the game is ran with Proton. If the AppID is set to an invalid one or an overlapping one, Steam will pick a new one usually but also has some weird behaviour where it doesn't know how to handle the AppID and can result in a mismatch of artwork being used in the grids folder. On the other hand, a user could use SME to force a given AppID for their shortcuts, so that compatdatas or grid names can be re-used.

Having a separate tab for shortcuts could just make for a "cleaner" workflow, being able to view and edit details for all Non-Steam Games. I think many of the existing properties would not be applicable though, since you can't really set description, publisher, etc for a Non-Steam title anywhere to my knowledge.

I think this is moreso looking for a use-case than having a definitive one, but just tossing my hat into the ring here because I have spent a ridiculous amount of time over the last couple of months digging deep into shortcuts.vdf and related files to understand how Steam stores information about shortcuts.


I should note that shortcuts.vdf is only one piece of the puzzle when it comes to editing information about Non-Steam Games. Steam stores information in a few different places now, mainly localconfig.vdf, some information is required to be parsed from a LevelDB store, and for some Linux-specific tasks, config.vdf needs to be edited.

  1. Shortcut information is stored in the binary shortcuts.vdf file. The format is known and the start and end hex for each fields and how to extract that information makes it feasible to edit this information. However, some information in this file is required for Steam to see the entry structure as valid, but Steam will not read or update some of these fields. For example, you need to specify the AllowOverlay field with a valid 0x01 or 0x00, but Steam won't read or update this. Instead, this is stored in localconfig.vdf.

  2. The localconfig.vdf is a text-based VDF config file in the same directory as the binary shortcuts.vdf file. This contains an Apps section which then has groups for each Non-Steam AppID (and only Non-Steam Apps here), though it uses the signed 32bit integer and not the standard unsigned 32bit integer used for things like CompatToolMapping in the text-based config.vdf, or for setting artwork. These groups have two fields: OverlayAppEnable and DisableLaunchInVR. The OverlayAppEnable is actually what controls whether a Non-Steam game has the Steam Overlay, and is no longer read from shortcuts.vdf. The same goes for the shortcuts.vdf's DisableLaunchInVR, which is the inverse of the OpenVR property in shortcuts.vdf.

    "Apps"
    {
        "-222353304"
        {
            "OverlayAppEnable"      "0"
            "DisableLaunchInVR"     "1"
        }
    }
  3. Though shortcuts.vdf does contain an IsHidden property and this again must be present, it is actually controlled separately in localconfig.vdf, in a user-collection property under the WebStorage section. This is a stringified JSON value which contains information about which collections a Non-Steam Game is a part of. One of these collections is hidden, and the structure looks like this:

    "user-collections"       "{\"uc-1QwE3sdxpu7J\":{\"id\":\"uc-1QwE3sdxpu7J\",\"added\":[appid],\"removed\":[]},\"hidden\":{\"id\":\"hidden\",\"added\":[appid, appid, appid],\"removed\":[]}}"
  4. For general collections, they are also inserted into the above stringified JSON. The uc-1QwE3sdxpu7J is the name of one of the collections I have put a Non-Steam Game into. The tricky part here is where this name comes from. For older collections before the library update, they are named from-tag-tagname, but since the library update, they're named like the entry above. These are always prefixed with uc-, and the part after that is the LevelDB key used for the collection in Steam's LevelDB where it tracks which Steam native AppIDs are part of which collection. This LevelDB is at $HOME/.local/share/Steam/config/htmlcache/Local Storage/ (see Steam-ROM-Manager), or the equivalent path on Windows and macOS. I am actually in the process of figuring out a way to parse shortcuts out of this for SteamTinkerLaunch, but SME could likely utilise something like plyvel to accomplish this.

  5. Finally, for setting the compatibility tool used by any Steam game including Non-Steam Games, this is controlled by a CompatToolMapping entry in config.vdf based on the 32bit unsigned integer (different from the one used in localconfig.vdf's Apps section!). It follows the same format as Steam native compatibility tool mapping entries.

If support for Steam shortcuts is added, hopefully that provides some useful hints on potential implementation details, or perhaps it could weigh a factor on whether implementing support is worth the implementation and maintenance burden :-)