summaryrefslogtreecommitdiff
path: root/steam.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'steam.lisp')
-rw-r--r--steam.lisp109
1 files changed, 85 insertions, 24 deletions
diff --git a/steam.lisp b/steam.lisp
index 8d61514..5bc49a8 100644
--- a/steam.lisp
+++ b/steam.lisp
@@ -1,3 +1,5 @@
+(in-package :arclade)
+
(defvar steam-host "api.steampowered.com")
(defun set-steam-key (key)
@@ -14,60 +16,119 @@
;; an array named "item" containing several objects following the "item" structure).
;; * Null is represented as JSON's null.
-
(defun steam-games-uri ()
+ "Builds the uri & query params to get owned games for the configured steam id."
(quri:render-uri
(quri:make-uri-http
:host steam-host
:path "IPlayerService/GetOwnedGames/v0001/"
:query (quri:url-encode-params `(("key" . ,(steam-key *config*))
- ("steamid" . ,(steam-user-id *config*))
- ("include_appinfo" . "true"))))))
+ ("steamid" . ,(steam-user-id *config*))
+ ("include_appinfo" . "true"))))))
(defun fetch-steam-games ()
+ "Fetch configured user's steam games and return parsed JSON."
(derrida:with-keypaths ((games :|response| :|games|))
(json:parse
(flexi-streams:octets-to-string
- (drakma:http-request (steam-games-uri))))
+ (drakma:http-request (steam-games-uri))))
games))
-(defun make-steam-game (json)
+(defun make-steam-game (data)
+ "Make a STEAM-GAME instance from DATA, a parsed JSON form from Steam's API."
(with-plist ((id :|appid|) (playtime :|playtime_forever|) (name :|name|)
- (icon-url :|img_icon_url|) (last-played :|rtime_last_played|))
- json
+ (icon-url :|img_icon_url|) (last-played :|rtime_last_played|))
+ data
(let ((game (make-instance 'steam-game :name name :appid id)))
(setf (playtime game) playtime
- (icon-url game) icon-url
- (last-played game) last-played)
+ (icon-url game) icon-url
+ (last-played game) last-played)
game)))
+(defun steam-game-schema-uri (game)
+ "Returns URI and query params to get detailed info about a game.
+
+RESULT DATA
+game
+ gameName (string)
+ Steam internal (non-localized) name of game.
+ gameVersion (int)
+ Steam release version number currently live on Steam.
+ availableGameStats
+ achievements (Optional) (array)
+ name (string)
+ API Name of achievement.
+ defaultvalue (int)
+ Always 0 (player's default state is unachieved).
+ displayName (string)
+ Display title string of achievement.
+ hidden (int)
+ If achievement is hidden to the user before earning
+ achievement, value is 1. 0 if public.
+ description (string)
+ Display description string of achievement.
+ icon (string)
+ Absolute URL of earned achievement icon art.
+ icongray (string)
+ Absolute URL of un-earned achievement icon art."
+ (quri:render-uri
+ (quri:make-uri-http
+ :host steam-host
+ :path "ISteamUserStats/GetSchemaForGame/v2/"
+ :query (quri:url-encode-params `(("key" . ,(steam-key *config*))
+ ("appid" . ,(appid game))
+ ("l" . "en"))))))
+
+(defun fetch-steam-game-schema (game)
+ (derrida:with-keypaths ((achievements :|game| :|availableGameStats| :|achievements|))
+ (json:parse
+ (flexi-streams:octets-to-string
+ (drakma:http-request (steam-game-schema-uri game))))
+ achievements))
+
(defun steam-achievements-uri (game)
+ "Builds uri & query params for configured steam id's achievements for GAME."
(quri:render-uri
(quri:make-uri-http
:host steam-host
:path "ISteamUserStats/GetPlayerAchievements/v0001/"
:query (quri:url-encode-params `(("key" . ,(steam-key *config*))
- ("steamid" . ,(steam-user-id *config*))
- ("appid" . ,(appid game))
- ("l" . "en"))))))
+ ("steamid" . ,(steam-user-id *config*))
+ ("appid" . ,(appid game))
+ ("l" . "en"))))))
(defun fetch-steam-achievements (steam-game)
(derrida:with-keypaths ((success :|playerstats| :|success|)
- (achievements :|playerstats| :|achievements|))
+ (achievements :|playerstats| :|achievements|))
(json:parse
(flexi-streams:octets-to-string
- (drakma:http-request (steam-achievements-uri steam-game))))
+ (drakma:http-request (steam-achievements-uri steam-game))))
(when success achievements)))
-(defun steam-game-schema-uri (game)
- "Returns URI and query params to get detailed info about a game. This is where
-the image links for achievements can be found."
- (quri:render-uri
- (quri:make-uri-http
- :host steam-host
- :path "ISteamUserStats/GetSchemaForGame/v2/"
- :query (quri:url-encode-params `(("key" . ,(steam-key *config*))
- ("appid" . ,(appid game))
- ("l" . "en"))))))
+(defun make-steam-achievement (game schema stats)
+ (with-plist ((icon :|icon|) (icongray :|icongray|))
+ schema
+ (with-plist ((name :|name|) (desc :|description|) (time :|unlocktime|)
+ (achieved :|achieved|) (apiname :|apiname|))
+ stats
+ (db:with-transaction ()
+ (let ((rec (make-instance 'steam-achievement
+ :game game :name name :description desc)))
+ (setf (icon rec) icon
+ (icongray rec) icongray
+ (apiname rec) apiname)
+ (unless (zerop achieved)
+ (setf (fulfillment rec) (epoch-time time)))
+ rec)))))
+(defun load-steam-games ()
+ "Fetch and wrap STEAM-GAMES as persistent objects.
+WARNING! Not idempotent!"
+ (db:with-transaction ()
+ (loop for data in (fetch-steam-games)
+ do (make-steam-game data))))
+(defun load-achievement-data (game)
+ (loop for schema in (fetch-steam-game-schema game)
+ for achievements in (fetch-steam-achievements game)
+ do (make-steam-achievement game schema achievements)))