api.rkt 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #lang racket
  2. (provide send-ping send-message send-join send-users
  3. (struct-out chat-message)
  4. is-chat-message? get-chat-message
  5. is-notify? get-notify
  6. (struct-out event-data)
  7. is-event? get-event-data
  8. is-users-reply? get-users-reply)
  9. (require net/rfc6455 ;; web sockets
  10. json
  11. "macros.rkt"
  12. )
  13. (define (send-jsexpr c js)
  14. (when (ws-conn-closed? c)
  15. (error "trying to send-jsexpr to a closed connection"
  16. (ws-conn-close-status c)
  17. (ws-conn-close-reason c)))
  18. (ws-send! c (jsexpr->string js)))
  19. (define/contract (send-ping conn)
  20. (-> ws-conn? void?)
  21. (send-jsexpr conn (hasheq 'Type CdPing 'Message "")))
  22. (define/contract (send-message conn msg)
  23. (-> ws-conn? string? void?)
  24. (send-jsexpr conn (hasheq 'Type CdMessage 'Message msg)))
  25. (define/contract (send-join conn name color)
  26. (-> ws-conn? string? string? void?)
  27. (define jd
  28. (jsexpr->string (hasheq 'Name name 'Color color)))
  29. (send-jsexpr conn (hasheq 'Type CdJoin 'Message jd)))
  30. (define/contract (send-users conn)
  31. (-> ws-conn? any)
  32. (send-jsexpr conn (hasheq 'Type CdUsers 'Message "")))
  33. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  34. ;; is it a reply to the /users command?
  35. (define/contract (is-users-reply? js)
  36. (-> jsexpr? boolean?)
  37. (and (= DTHidden (hash-ref js 'Type -1))
  38. (= CdUsers (hash-ref (hash-ref js 'Data) 'Type -1))))
  39. (define/contract (get-users-reply js)
  40. (-> is-users-reply? (listof string?))
  41. (hash-ref (hash-ref js 'Data) 'Data))
  42. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  43. (struct event-data (type payload) #:transparent)
  44. (define/contract (is-event? js)
  45. (-> jsexpr? boolean?)
  46. (= DTEvent (hash-ref js 'Type -1)))
  47. ;; bad code
  48. (define (convert-event-data-type t)
  49. (cond
  50. [(= t EvJoin) 'join]
  51. [(= t EvLeave) 'leave]
  52. [(= t EvKick) 'kick]
  53. [(= t EvBan) 'ban]
  54. [(= t EvServerMessage) 'server-message]
  55. [(= t EvNameChange) 'name-changed]
  56. [(= t EvNameChangeForced) 'name-change-forced]
  57. [else 'unknown]))
  58. (define/contract (get-event-data js)
  59. (-> is-event? event-data?)
  60. (define data (hash-ref js 'Data))
  61. (event-data (convert-event-data-type (hash-ref data 'Event))
  62. (hash-ref data 'User "")))
  63. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  64. (define/contract (is-notify? js)
  65. (-> jsexpr? boolean?)
  66. (and (= DTHidden (hash-ref js 'Type -1))
  67. (= CdNotify (hash-ref (hash-ref js 'Data) 'Type -1))))
  68. (define/contract (get-notify js)
  69. (-> is-notify? string?)
  70. (hash-ref (hash-ref js 'Data) 'Data))
  71. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  72. (struct chat-message
  73. (message from color type)
  74. #:transparent)
  75. (define/contract (is-chat-message? js)
  76. (-> jsexpr? boolean?)
  77. (= DTChat (hash-ref js 'Type 0)))
  78. ;; XXX: this code is bad
  79. (define (convert-type t)
  80. (cond
  81. [(= t MsgChat) 'chat]
  82. [(= t MsgAction) 'action]
  83. [(= t MsgServer) 'server]
  84. [(= t MsgError) 'error]
  85. [(= t MsgNotice) 'notice]
  86. [(= t MsgCommandResponse) 'response]
  87. [(= t MsgCommandError) 'command-error]
  88. [else 'unknown]))
  89. (define/contract (get-chat-message js)
  90. (-> jsexpr? chat-message?)
  91. (define data (hash-ref js 'Data))
  92. (chat-message (hash-ref data 'Message)
  93. (hash-ref data 'From)
  94. (hash-ref data 'Color)
  95. (convert-type (hash-ref data 'Type))))