(ns advent.steam (:require [play-clj.core :refer :all] [clojure.edn :as edn]) (:import [java.nio ByteBuffer CharBuffer])) (def has-steam? (try (import '[com.codedisaster.steamworks SteamUserStats SteamUserStatsCallback SteamAPI SteamRemoteStorage]) true (catch Exception e false))) (defn init [] (when has-steam? (eval `(SteamAPI/init)))) (defn update [] (when (and has-steam? (eval `(SteamAPI/isSteamRunning))) (eval `(SteamAPI/runCallbacks)))) (defn achievement-fn [f achievement] (when has-steam? (eval `(let [stats# (atom nil)] (reset! stats# (SteamUserStats. (reify SteamUserStatsCallback (onUserStatsReceived [this# game-id# steam-user-id# result#] (~f @stats# ~achievement) ) (onUserStatsStored [this# gameId# result#] ) (onUserAchievementStored [_ _ _ _ _ _] )))) (.requestCurrentStats @stats#))))) (def set-achievement (partial achievement-fn (fn [stats achievement] (.setAchievement stats achievement) (.storeStats stats)))) (def clear-achievement (partial achievement-fn (fn [stats achievement] (.clearAchievement stats achievement) (.storeStats stats)))) (def all-achievements ["MASTER_SLEUTH"]) (defn clear-all-achievements [] (doall (map clear-achievement all-achievements))) (defn write-file [filename edn] (let [edn (pr-str edn)] (if has-steam? (eval `(let [rs# (SteamRemoteStorage. nil) v# ~edn bb# (ByteBuffer/allocateDirect (* 2 (count v#)))] (-> bb# .asCharBuffer (.put v#) ) (.fileWrite rs# ~filename bb# (* 2 (count v#))))) (let [f (files! :local filename)] (.writeString f edn false))))) (defn snapshot-list [] (if has-steam? (eval `(let [rs# (SteamRemoteStorage. nil)] (for [i# (range (.getFileCount rs#)) :let [len# (* 1024 1024) n# (.getFileNameAndSize rs# i# (make-array Integer/TYPE 1)) bb# (ByteBuffer/allocateDirect len#)] :when (.endsWith n# ".edn")] (do (println n#) (.fileRead rs# n# bb# len#) (-> bb# .asCharBuffer .toString edn/read-string))))) (for [save-file (.list (files! :local ".") ".edn")] (edn/read-string (.readString save-file))))) (defn add-screenshot [filename] (when has-steam? (eval `(let [rs# (SteamRemoteStorage. nil) bytes# (.readBytes (files! :local ~filename)) bb# (ByteBuffer/allocateDirect (count bytes#))] (.put bb# bytes#) (.fileWrite rs# ~filename bb# (count bytes#)))))) (defn download-screenshot [filename] (when (and has-steam? (not (.exists (files! :local filename)))) (eval `(let [rs# (SteamRemoteStorage. nil) len# (.getFileSize rs# ~filename) bb# (ByteBuffer/allocateDirect len#) bytes# (make-array Byte/TYPE len#)] (do (.fileRead rs# ~filename bb# len#) (.get bb# bytes#) (.writeBytes (files! :local ~filename) bytes# false))))))