From e5c77ceaca623d6d8d9ee932b66f1a0f8a6fdfe3 Mon Sep 17 00:00:00 2001 From: shoshin Date: Sun, 26 Mar 2023 09:12:55 -0500 Subject: Add: basic setup for getting steam achievements --- arclade.asd | 1 + model.lisp | 20 ++++++++++++++++++++ steam.lisp | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/arclade.asd b/arclade.asd index a5fd583..c1e8829 100644 --- a/arclade.asd +++ b/arclade.asd @@ -8,6 +8,7 @@ :serial t :depends-on (#:bknr.datastore + #:date-calc #:defclass-std #:derrida #:drakma diff --git a/model.lisp b/model.lisp index 4c13185..ce537cf 100644 --- a/model.lisp +++ b/model.lisp @@ -1,5 +1,9 @@ ;;;; model.lisp +(defclass player () + ((name :initarg :name :reader name) + (games :accessor games))) + (defclass game () ((name :initarg :name :reader name) (rating :accessor rating) @@ -9,3 +13,19 @@ (defclass steam-game (game) ((appid :initarg :appid :reader appid))) + +(defmethod print-object ((object steam-game) stream) + (format stream "#" (name object))) + +(defclass feat () + ((game :initarg :game :reader game) + (player :initarg :player :reader player) + (date :accessor date + :initform (multiple-value-list (date-calc:today-and-now))) + (description :accessor description :initform ""))) + +(defclass achievement (feat) + ((name :initarg :name :reader name))) + +(defclass score (feat) + ((points :initarg :points :accessor points))) diff --git a/steam.lisp b/steam.lisp index 0e29c73..8d61514 100644 --- a/steam.lisp +++ b/steam.lisp @@ -6,6 +6,15 @@ (defun set-steam-id (id) (setf (steam-user-id *config*) id)) +;; JSON +;; * The API returns an object containing the named object with the result data. +;; * Arrays are represented as an array with the name of the type of the objects +;; in the array (ie. an object named "items" containing an array of objects +;; of type "item" would be represented as an object named "items" containing +;; an array named "item" containing several objects following the "item" structure). +;; * Null is represented as JSON's null. + + (defun steam-games-uri () (quri:render-uri (quri:make-uri-http @@ -15,11 +24,12 @@ ("steamid" . ,(steam-user-id *config*)) ("include_appinfo" . "true")))))) -(defun steam-games () - (cadadr - (json:parse - (flexi-streams:octets-to-string - (drakma:http-request (steam-games-uri)))))) +(defun fetch-steam-games () + (derrida:with-keypaths ((games :|response| :|games|)) + (json:parse + (flexi-streams:octets-to-string + (drakma:http-request (steam-games-uri)))) + games)) (defun make-steam-game (json) (with-plist ((id :|appid|) (playtime :|playtime_forever|) (name :|name|) @@ -30,3 +40,34 @@ (icon-url game) icon-url (last-played game) last-played) game))) + +(defun steam-achievements-uri (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")))))) + +(defun fetch-steam-achievements (steam-game) + (derrida:with-keypaths ((success :|playerstats| :|success|) + (achievements :|playerstats| :|achievements|)) + (json:parse + (flexi-streams:octets-to-string + (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")))))) + + -- cgit v1.2.3