first commit
This commit is contained in:
67
discord-ipc.rkt
Normal file
67
discord-ipc.rkt
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#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))))
|
||||||
16
info.rkt
Normal file
16
info.rkt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#lang info
|
||||||
|
|
||||||
|
(define name "Discord Rich Presence")
|
||||||
|
(define version "0.1")
|
||||||
|
(define pkg-desc "Updates Discord status with filename, line count, and running state from DrRacket.")
|
||||||
|
(define pkg-authors '(joren))
|
||||||
|
(define license 'MIT)
|
||||||
|
|
||||||
|
(define drracket-tools '(("tool.rkt")))
|
||||||
|
(define drracket-tool-names '("Discord Presence"))
|
||||||
|
|
||||||
|
(define deps '("base"
|
||||||
|
"drracket-plugin-lib"
|
||||||
|
"gui-lib"
|
||||||
|
"unix-socket-lib"))
|
||||||
|
|
||||||
66
tool.rkt
Normal file
66
tool.rkt
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#lang racket/gui
|
||||||
|
(require drracket/tool
|
||||||
|
racket/unit
|
||||||
|
racket/class
|
||||||
|
"discord-ipc.rkt")
|
||||||
|
|
||||||
|
(provide tool@)
|
||||||
|
|
||||||
|
(define CLIENT-ID "1456391630356746343")
|
||||||
|
|
||||||
|
(define tool@
|
||||||
|
(unit
|
||||||
|
(import drracket:tool^)
|
||||||
|
(export drracket:tool-exports^)
|
||||||
|
(define phase1 void)
|
||||||
|
(define phase2 void)
|
||||||
|
|
||||||
|
(connect-discord CLIENT-ID)
|
||||||
|
|
||||||
|
(define start-time (current-seconds))
|
||||||
|
(define (update-status tab [override-running #f])
|
||||||
|
(define defs (send tab get-defs))
|
||||||
|
(define filename
|
||||||
|
(let ([path (send defs get-filename)])
|
||||||
|
(if path (path->string (file-name-from-path path)) "Untitled")))
|
||||||
|
(define line-count (add1 (send defs last-paragraph)))
|
||||||
|
(define is-running? (or override-running (send tab is-running?)))
|
||||||
|
(define details (if is-running?
|
||||||
|
(format "Running ~a" filename)
|
||||||
|
(format "Editing ~a" filename)))
|
||||||
|
(define state (format "~a lines" line-count))
|
||||||
|
(update-presence details state
|
||||||
|
#:start start-time
|
||||||
|
#:small-text (if is-running? "Running" "Editing")))
|
||||||
|
|
||||||
|
(drracket:get/extend:extend-tab
|
||||||
|
(mixin (drracket:unit:tab<%>) ()
|
||||||
|
(super-new)
|
||||||
|
(define/override (disable-evaluation)
|
||||||
|
(super disable-evaluation)
|
||||||
|
(update-status this #t))
|
||||||
|
|
||||||
|
(define/override (enable-evaluation)
|
||||||
|
(super enable-evaluation)
|
||||||
|
(update-status this #f))))
|
||||||
|
|
||||||
|
(drracket:get/extend:extend-definitions-text
|
||||||
|
(mixin (drracket:unit:definitions-text<%> editor<%>) ()
|
||||||
|
(super-new)
|
||||||
|
(define/augment (after-save-file success?)
|
||||||
|
(inner (void) after-save-file success?)
|
||||||
|
(when success?
|
||||||
|
(update-status (send this get-tab))))))
|
||||||
|
|
||||||
|
(drracket:get/extend:extend-unit-frame
|
||||||
|
(mixin (drracket:unit:frame<%>) ()
|
||||||
|
(super-new)
|
||||||
|
(define/augment (on-tab-change old-tab new-tab)
|
||||||
|
(inner (void) on-tab-change old-tab new-tab)
|
||||||
|
(update-status new-tab))
|
||||||
|
|
||||||
|
(define/override (on-activate active?)
|
||||||
|
(super on-activate active?)
|
||||||
|
(when active?
|
||||||
|
(update-status (send this get-current-tab))))))))
|
||||||
|
|
||||||
Reference in New Issue
Block a user