diff options
Diffstat (limited to 'steam.lisp')
-rw-r--r-- | steam.lisp | 109 |
1 files changed, 85 insertions, 24 deletions
@@ -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))) |