@@ -6,16 +6,19 @@ extends Library
6
6
# ~/.steam/steam/userdata/<user_id>/config/localconfig.vdf
7
7
8
8
const SteamClient := preload ("res://plugins/steam/core/steam_client.gd" )
9
+ const SteamAPIClient := preload ("res://plugins/steam/core/steam_api_client.gd" )
9
10
const _apps_cache_file : String = "apps.json"
10
11
11
12
var thread_pool := load ("res://core/systems/threading/thread_pool.tres" ) as ThreadPool
13
+ var steam_api_client := SteamAPIClient .new ()
12
14
13
15
@onready var steam : SteamClient = get_tree ().get_first_node_in_group ("steam_client" )
14
16
15
17
16
18
# Called when the node enters the scene tree for the first time.
17
19
func _ready () -> void :
18
20
super ()
21
+ add_child (steam_api_client )
19
22
logger = Log .get_logger ("Steam" , Log .LEVEL .DEBUG )
20
23
logger .info ("Steam Library loaded" )
21
24
steam .logged_in .connect (_on_logged_in )
@@ -131,7 +134,8 @@ func _on_logged_in(status: SteamClient.LOGIN_STATUS):
131
134
if not LibraryManager .has_app (item .name ):
132
135
var msg := "App {0} was not loaded. Adding item" .format ([item .name ])
133
136
logger .info (msg )
134
- LibraryManager .add_library_launch_item (library_id , item )
137
+ launch_item_added .emit (item )
138
+ # LibraryManager.add_library_launch_item(library_id, item)
135
139
# TODO: Update installed status
136
140
137
141
# TODO: Remove library items that have been deleted
@@ -168,9 +172,10 @@ func _load_library(
168
172
return []
169
173
170
174
logger .info ("Fetching Steam library..." )
175
+
171
176
# Get all available apps
172
- var app_ids : PackedInt64Array = await _get_available_apps ()
173
- var app_info : Dictionary = await _get_games_from_app_info (app_ids )
177
+ var app_ids : PackedInt64Array = await get_available_apps ()
178
+ var app_info : Dictionary = await get_apps_info (app_ids )
174
179
var apps_installed : Array = await steam .get_installed_apps ()
175
180
var app_ids_installed := PackedStringArray ()
176
181
for app in apps_installed :
@@ -179,13 +184,11 @@ func _load_library(
179
184
# Generate launch items for each game
180
185
var items := [] as Array [LibraryLaunchItem ]
181
186
for app_id in app_info .keys ():
182
- var item : LibraryLaunchItem = LibraryLaunchItem .new ()
183
- item .provider_app_id = "{0} " .format ([app_id ])
184
- item .name = app_info [app_id ]
185
- item .command = "steam"
186
- item .args = ["-gamepadui" , "-steamos3" , "-steampal" , "-steamdeck" , "-silent" , "steam://rungameid/" + item .provider_app_id ]
187
- item .tags = ["steam" ]
188
- item .installed = app_id in app_ids_installed
187
+ var info := app_info [app_id ] as Dictionary
188
+ var item := _app_info_to_launch_item (info , app_id in app_ids_installed )
189
+ if not item :
190
+ logger .debug ("Unable to create launch item for: " + app_id )
191
+ continue
189
192
items .append (item )
190
193
191
194
# Cache the discovered apps
@@ -202,65 +205,89 @@ func _load_library(
202
205
203
206
204
207
# Returns an array of available steamAppIds
205
- func _get_available_apps () -> Array :
208
+ func get_available_apps () -> Array :
206
209
var app_ids = await steam .get_available_apps ()
207
210
return app_ids
208
211
209
212
210
- # Returns the app status for the given app ids
211
- func _get_app_status (app_ids : Array ) -> Dictionary :
212
- var app_status := {}
213
- for app_id in app_ids :
214
- var id := str (app_id )
215
- var status := await steam .get_app_status (app_id )
216
- app_status [app_id ] = status
217
- return app_status
218
-
219
-
220
- # Returns the app information for the given app ids
221
- func _get_games_from_app_info (app_ids : Array , caching_flags : int = Cache .FLAGS .LOAD | Cache .FLAGS .SAVE ) -> Dictionary :
213
+ ## Returns the app information for the given app ids. This is returned as a
214
+ ## dictionary where the key is the app ID, and the value is the app info.
215
+ func get_apps_info (app_ids : Array , caching_flags : int = Cache .FLAGS .LOAD | Cache .FLAGS .SAVE ) -> Dictionary :
222
216
var app_info := {}
223
217
for app_id in app_ids :
224
218
var id := str (app_id )
225
- var info := await _get_app_info (id , caching_flags )
219
+ var info := await get_app_info (id , caching_flags )
226
220
227
221
if not id in info :
228
222
continue
229
- if not "common" in info [id ]:
230
- continue
231
- if not "type" in info [id ]["common" ]:
232
- continue
233
- if info [id ]["common" ]["type" ] != "Game" : # Skip non-games
234
- continue
235
- if not "name" in info [id ]["common" ]:
236
- continue
237
- app_info [id ] = info [id ]["common" ]["name" ]
223
+
224
+ app_info [id ] = info
238
225
239
226
return app_info
240
227
241
228
242
229
## Returns the app info dictionary parsed from the VDF
243
- func _get_app_info (app_id : String , caching_flags : int = Cache .FLAGS .LOAD | Cache .FLAGS .SAVE ) -> Dictionary :
230
+ func get_app_info (app_id : String , caching_flags : int = Cache .FLAGS .LOAD | Cache .FLAGS .SAVE ) -> Dictionary :
244
231
# Load the app info from cache if requested
245
232
var cache_key := app_id + ".app_info"
246
233
if caching_flags & Cache .FLAGS .LOAD and Cache .is_cached (_cache_dir , cache_key ):
247
234
return Cache .get_json (_cache_dir , cache_key )
248
235
else :
249
- var info := await steam .get_app_info (app_id )
236
+ var info = await steam_api_client .get_app_details (app_id )
237
+ logger .debug ("Found app info for " + app_id + ": " + str (info ))
238
+ if info == null :
239
+ return {}
250
240
if caching_flags & Cache .FLAGS .SAVE :
251
241
Cache .save_json (_cache_dir , cache_key , info )
252
242
return info
253
243
254
244
245
+ ## Builds a library launch item from the given Steam app information from the store API.
246
+ func _app_info_to_launch_item (info : Dictionary , is_installed : bool ) -> LibraryLaunchItem :
247
+ if info .size () == 0 :
248
+ return null
249
+
250
+ var app_id := info .keys ()[0 ] as String
251
+ var details := info [app_id ] as Dictionary
252
+ if not "data" in details :
253
+ return null
254
+ var data := details ["data" ] as Dictionary
255
+ if not "type" in data :
256
+ return null
257
+ if not data ["type" ] == "game" :
258
+ return null
259
+ var categories := PackedStringArray ()
260
+ if "categories" in data :
261
+ for category in data ["categories" ]:
262
+ categories .append (category ["description" ])
263
+ var tags := PackedStringArray ()
264
+ if "genres" in data :
265
+ for genre in data ["genres" ]:
266
+ tags .append ((genre ["description" ] as String ).to_lower ())
267
+
268
+ var item := LibraryLaunchItem .new ()
269
+ item .provider_app_id = app_id
270
+ item .name = data ["name" ]
271
+ item .command = "steam"
272
+ item .args = ["-gamepadui" , "-steamos3" , "-steampal" , "-steamdeck" , "-silent" , "steam://rungameid/" + app_id ]
273
+ item .categories = categories
274
+ item .tags = ["steam" ]
275
+ item .tags .append_array (tags )
276
+ item .installed = is_installed
277
+
278
+ return item
279
+
280
+
255
281
# Returns whether or not the given app id has a Linux binary
256
282
func _app_supports_linux (app_id : String ) -> bool :
257
- var info : = await _get_app_info (app_id )
283
+ var info = await steam_api_client . get_app_details (app_id )
258
284
if not app_id in info :
259
285
return false
260
- if not "common" in info [app_id ]:
286
+ if not "data" in info [app_id ]:
287
+ return false
288
+ if not "platform" in info [app_id ]["data" ]:
261
289
return false
262
- if not "oslist " in info [app_id ]["common " ]:
290
+ if not "linux " in info [app_id ]["data" ][ "platform " ]:
263
291
return false
264
- var os_list := info [app_id ]["common" ]["oslist" ].split ("," ) as Array
265
292
266
- return " linux" in os_list
293
+ return info [ app_id ][ "data" ][ "platform" ][ " linux"]
0 commit comments