68 lines
2.1 KiB
Racket
68 lines
2.1 KiB
Racket
#lang racket/base
|
|
(require racket/unix-socket
|
|
json
|
|
racket/list
|
|
racket/os)
|
|
|
|
(provide connect-discord update-presence)
|
|
|
|
(define ipc-out #f)
|
|
|
|
(define (get-socket-path)
|
|
(define base-dirs
|
|
(list (getenv "XDG_RUNTIME_DIR")
|
|
(getenv "TMPDIR")
|
|
"/tmp"
|
|
(build-path "/run/user" (number->string (getpid)))))
|
|
|
|
(for/first ([dir base-dirs]
|
|
#:when dir
|
|
[i (in-range 10)]
|
|
#:do [(define p (build-path dir (format "discord-ipc-~a" i)))]
|
|
#:when (file-exists? p))
|
|
p))
|
|
|
|
(define (write-packet opcode payload)
|
|
(when ipc-out
|
|
(define json-bytes (string->bytes/utf-8 (jsexpr->string payload)))
|
|
(define len (bytes-length json-bytes))
|
|
|
|
(write-bytes (integer->integer-bytes opcode 4 #f #f) ipc-out) ; Opcode
|
|
(write-bytes (integer->integer-bytes len 4 #f #f) ipc-out) ; Length
|
|
(write-bytes json-bytes ipc-out)
|
|
(flush-output ipc-out)))
|
|
|
|
(define (connect-discord client-id)
|
|
(define path (get-socket-path))
|
|
(if path
|
|
(with-handlers ([exn:fail? (lambda (e) (printf "Discord connection failed.\n"))])
|
|
(define-values (in out) (unix-socket-connect path))
|
|
(set! ipc-out out)
|
|
(write-packet 0 (hash 'v 1 'client_id client-id))
|
|
(printf "Connected to Discord at ~a\n" path))
|
|
(printf "Discord not found.\n")))
|
|
|
|
(define (update-presence details state
|
|
#:start [start-timestamp #f]
|
|
#:small-text [small-text #f])
|
|
|
|
(define activity
|
|
(hash 'details details
|
|
'state state
|
|
'assets (hash
|
|
'large_image "racket-logo-ezgif_com-svg-to-png-converter"
|
|
'large_text "DrRacket"
|
|
|
|
'small_image (if small-text "lambda" #f)
|
|
'small_text small-text)
|
|
|
|
'timestamps (if start-timestamp
|
|
(hash 'start start-timestamp)
|
|
#f)))
|
|
|
|
(write-packet 1
|
|
(hash 'cmd "SET_ACTIVITY"
|
|
'nonce (number->string (current-milliseconds))
|
|
'args (hash 'pid (getpid)
|
|
'activity activity))))
|