mcarlucci / decky-storage-cleaner

A Decky Loader plugin for tidying up your Steam Deck's storage. Quickly visualize, select and clear shader cache and compatibility data.
https://plugins.deckbrew.xyz/
GNU General Public License v3.0
62 stars 1 forks source link

Question about appstore API? #7

Closed SteveImmanuel closed 9 months ago

SteveImmanuel commented 1 year ago

Hi, really nice plugin, I love it!

Just wondering, in your readme you mentioned that the game names are obtained using appStore.GetAppOverviewByGameID(game.appid. Looking at your, I only find the following line without any declaration before: https://github.com/mcarlucci/decky-storage-cleaner/blob/3515a3a13afd17f6f3bc3213f244cfb963c49b45/src/index.tsx#L83

Can you tell me what does it do and how does it work? Does it call external API or is there any documentation that I can refer to? I'm curious as to how it obtained the name of non-steam games because as I understand the appid of non-steam games are just randomly generated number, I'm not sure though.

mcarlucci commented 1 year ago

Check out line 85: https://github.com/mcarlucci/decky-storage-cleaner/blob/3515a3a13afd17f6f3bc3213f244cfb963c49b45/src/index.tsx#L85C1-L85C1

There, I am checking if the app_type property is equal to 1, which is how Steam identifies games under their digital rights management.

For non-steam games, Steam assigns the game a random id and the app_type is not equal to 1

I get a list of all the games on a users Steam Deck with the following python method: https://github.com/mcarlucci/decky-storage-cleaner/blob/3515a3a13afd17f6f3bc3213f244cfb963c49b45/main.py#L46

For example, here is the entire object returned for The Shadow of the Tomb Raider: appStore.GetAppOverviewByAppID(750920)

Returns:

{
  "appid": 750920,
  "display_name": "Shadow of the Tomb Raider",
  "app_type": 1,
  "mru_index": 13,
  "rt_recent_activity_time": 1682905807,
  "minutes_playtime_forever": 1303,
  "minutes_playtime_last_two_weeks": 325,
  "rt_last_time_played": 1682905807,
  "rt_last_time_locally_played": 1682905806,
  "per_client_data": [
    {
      "clientid": "0",
      "client_name": "This machine",
      "display_status": 11,
      "status_percentage": 100,
      "installed": true,
      "bytes_downloaded": "0",
      "bytes_total": "0",
      "is_available_on_current_platform": true,
      "cloud_status": 3
    }
  ],
  "most_available_clientid": "0",
  "selected_clientid": "0",
  "selected_per_client_data": {
    "clientid": "0",
    "client_name": "This machine",
    "display_status": 11,
    "status_percentage": 100,
    "installed": true,
    "bytes_downloaded": "0",
    "bytes_total": "0",
    "is_available_on_current_platform": true,
    "cloud_status": 3
  },
  "most_available_per_client_data": {
    "clientid": "0",
    "client_name": "This machine",
    "display_status": 11,
    "status_percentage": 100,
    "installed": true,
    "bytes_downloaded": "0",
    "bytes_total": "0",
    "is_available_on_current_platform": true,
    "cloud_status": 3
  },
  "local_per_client_data": {
    "clientid": "0",
    "client_name": "This machine",
    "display_status": 11,
    "status_percentage": 100,
    "installed": true,
    "bytes_downloaded": "0",
    "bytes_total": "0",
    "is_available_on_current_platform": true,
    "cloud_status": 3
  },
  "rt_last_time_played_or_installed": 1682905807,
  "rt_purchased_time": 1677300997,
  "rt_original_release_date": 0,
  "rt_steam_release_date": 1536940800,
  "icon_hash": "7db38cff16091c9c058892fcfeee102a6ed589d9",
  "controller_support": 2,
  "metacritic_score": 77,
  "size_on_disk": "37955541433",
  "visible_in_game_list": true,
  "rt_store_asset_mtime": 1667572921,
  "sort_as": "shadow of the tomb raider",
  "association": [
    {
      "type": 2,
      "name": "Eidos-Montréal"
    },
    {
      "type": 2,
      "name": "Crystal Dynamics"
    },
    {
      "type": 2,
      "name": "Nixxes"
    },
    {
      "type": 2,
      "name": "Feral Interactive (Mac)"
    },
    {
      "type": 2,
      "name": "Feral interactive (Linux)"
    },
    {
      "type": 1,
      "name": "Crystal Dynamics"
    },
    {
      "type": 1,
      "name": "Feral Interactive (Mac)"
    },
    {
      "type": 1,
      "name": "Feral interactive (Linux)"
    },
    {
      "type": 3,
      "name": "Tomb Raider"
    }
  ],
  "m_setStoreCategories": {},
  "m_setStoreTags": {},
  "canonicalAppType": 1,
  "review_score_with_bombs": 8,
  "review_percentage_with_bombs": 83,
  "review_score_without_bombs": 8,
  "review_percentage_without_bombs": 83,
  "steam_deck_compat_category": 2,
  "m_strPerClientData": "0,This machine,11,100,,true,,,,true,,,3",
  "m_strStoreTags": "21,19,7208,4182,1697,1695,1742,1664,1687,4106,3834,1662,4667,4166,1774,4345,1756,4342,3859,1680",
  "m_strAssociations": "2,Eidos-Montréal,2,Crystal Dynamics,2,Nixxes,2,Feral Interactive (Mac),2,Feral interactive (Linux),1,Crystal Dynamics,1,Feral Interactive (Mac),1,Feral interactive (Linux),3,Tomb Raider",
  "m_strStoreCategories": "2,22,23,28,29,33,41,42,43,45,46"
}
SteveImmanuel commented 1 year ago

Ah yes I understand that part. What I'm wondering is how does the appStore.GetAppOverviewByAppID retrieve the game name for non-steam games because the ID is just a randomly assigned number, isn't it?

mcarlucci commented 1 year ago

You are correct, Steam does randomly assign an id to non-steam games. They also create a game directory named after the id located in /.steam/steam/steamapps/. If not under the directory, I am not exactly sure how they are storing/retrieving the app metedata returned from appStore.GetAppOverviewByAppID()