Public
Authored by Michał "phoe" Herda

Protocol sketch

This protocol needs to have twin forms - we want an S-expression-based format for natural communication with Lisp and JSON-based format for communicating with the rest of the world.

All tests must be performed using both protocol variants.


Proposed dynamic reconnection flow:

((C 0) HELLO "Gateway" "pre-alpha")

((C 0) (OK HELLO) "Gateway" "pre-alpha" "Origin" "Welcome to Gateway Origin!")

((C 1) LOGIN :EMAIL "aza@dorano.com" :PASSWORD "SuperSecretPassword")

((C 1) (OK LOGIN) "08b6f29aee28f9bc27c397a52bfa9c51")
;; connection 1 established

;; -----------------------

((C 0) HELLO "Gateway" "pre-alpha")

((C 0) (OK HELLO) "Gateway" "pre-alpha" "Origin" "Welcome to Gateway Origin!")

((C 1) LOGIN :EMAIL "aza@dorano.com" :PASSWORD "SuperSecretPassword")

((C 1) (OK LOGIN) "3c287a9377bf0cad2738108b74e7dab")
;; connection 2 established

;; -----------------------

((C 0) HELLO "Gateway" "pre-alpha")

((C 0) (OK HELLO) "Gateway" "pre-alpha" "Origin" "Welcome to Gateway Origin!")

((C 1) LOGIN :COOKIE "08b6f29aee28f9bc27c397a52bfa9c51")

((C 1) (WARNING COOKIE-USED-ELSEWHERE LOGIN) "1.2.3.4")

((C 1) LOGIN :COOKIE "08b6f29aee28f9bc27c397a52bfa9c51")

((C 2) (OK LOGIN) "08b6f29aee28f9bc27c397a52bfa9c51")
;; connection 1 is killed: (QUIT COOKIE-USED-ELSEWHERE)
;; connection 1' is established

Proposed translation of the first connection and login attempt into JSON:

{
    "id": ["C", "0"],
    "command": "HELLO"
    "data": {
        "client-type": "Gateway",
        "version": "pre-alpha"
    }
}

{
    "id": ["C", "0"],
    "status": "OK",
    "command": "HELLO",
    "data": {
        "server-type": "Gateway",
        "version": "pre-alpha",
        "name": "Origin",
        "motd": "Welcome to Gateway Origin!"
    }
}

{
    "id": ["C", "1"],
    "command": "LOGIN",
    "data": {
        "email": "aza@dorano.com",
        "password": "SuperSecretPassword"
    }
}

{
    "id": ["C", "1"],
    "status": "OK",
    "command": "LOGIN",
    "data": {
        "cookie": "08b6f29aee28f9bc27c397a52bfa9c51"
    }
}

Proposed session:

((C 0) HELLO "Gateway" "pre-alpha") ;; ((C 0) ACK)

((C 0) (OK HELLO) "Gateway" "pre-alpha" "Origin" "Welcome to Gateway Origin!") ;; ((C 0) ACK)

((C 1) LOGIN :EMAIL "aza@dorano.com" :PASSWORD "SuperSecretPassword") ;; ...

((C 1) (OK LOGIN) "3c287a9377bf0cad2738108b74e7dab") ;; ...

((C 2) DESCRIBE-GATEWAY)

((C 2) (OK DESCRIBE-GATEWAY) 301 0 5
       (("066e36f472fe11e8adc0fa7ae01bbebc"
         "Lots of Very Good RP" 80 6 5 3 PUBLIC 1529328320
         "453d9b8b2beb42ffbe747c0fe1477615")
        ("066e3c3a72fe11e8adc0fa7ae01bbebc"
         "The Castle of Raptors" 16 2 2 2 PRIVATE 1529322511
         "0dc7bff41c6a40ebbbd04ab63b555506")
        ("066e3dac72fe11e8adc0fa7ae01bbebc"
         "Generic Modern RP Timeline" 18 2 3 2 PUBLIC 1529319908
         "8f5b1d876f9949018f007ae7a20e2f3c")
        ("066e3ed872fe11e8adc0fa7ae01bbebc"
         "Middle Earth And Middle Moon" 440 13 40 13 PUBLIC 1529328092
         "2821e30624894ba0b50917c3ca86d281")
        ("066e410872fe11e8adc0fa7ae01bbebc"
         "Actually This Is Just Casual Chat Here" 1836 103 184 35 PUBLIC 1529359662
         "933e712a927f4374b95caa3bb6ea0412")))

((C 3) DESCRIBE-TIMELINE "3364f6760e4f4575beee052f4e3a0462")

((C 3) (OK DESCRIBE-TIMELINE)
       "3364f6760e4f4575beee052f4e3a0462"2 0 2
       (("066e422072fe11e8adc0fa7ae01bbebc"
         "Prologue" 14 2 2 1529322317
         "df8197ecb5824eb881b3696e6455f6ad")
        ("066e45f472fe11e8adc0fa7ae01bbebc"
         "Chapter 1 - First Raptors" 2 2 2 1529322511
         "0dc7bff41c6a40ebbbd04ab63b555506")))

((C 4) DESCRIBE-PERSONA "0dc7bff41c6a40ebbbd04ab63b555506")

((C 4) (OK DESCRIBE-PERSONA)
       "033345b28d1c4639b8cc5db6bc023ad0"
       "Aza d'Orano" F
       "Just another raptoress who happens to be a young mage woman.")

;; TODO continue this

Proposed mapping:

(define-client-request hello ()
  (client-type version)
  (:ok (server-type version name &optional (motd "")))
  ((:warning cookie-used-elsewhere) (ip-address)))

(define-client-request login ()
  (&key email password cookie)
  (:ok (cookie))
  ((:error password-expired) ())
  ((:error invalid-credentials) ())
  ((:error account-banned) (&optional (reason ""))))

(define-client-request describe-gateway ()
  ()
  (:ok (total-timelines start count &list (timelines timeline))))

(define-mapping-from-request timeline ()
  ((uuid :type string
         :mapper #'uuid-string-to-octets)
   (name :type string)
   (nposts :type unsigned-byte)
   (nchapters :type unsigned-byte)
   (npersonas :type unsigned-byte)
   (nplayers :type unsigned-byte)
   (type :type symbol
         :mapper #'timeline-symbol-to-keyword)
   (last-modified-timestamp :type unsigned-byte
                            :mapper #'timestamp-unix-to-date)
   (last-modified-persona :type string
                          :mapper #'uuid-string-to-octets)))

(define-client-request describe-timeline ()
  (uuid)
  (:ok (uuid total-chapters start count &list (chapters chapter)))
  ((:error not-found) (uuid)))

(define-mapping-from-request chapter ()
  ((uuid :type string
         :mapper #'uuid-string-to-octets)
   (name :type string)
   (nposts :type unsigned-byte)
   (npersonas :type unsigned-byte)
   (nplayers :type unsigned-byte)
   (last-modified-timestamp :type unsigned-byte
                            :mapper #'timestamp-unix-to-date)
   (last-modified-persona :type string
                          :mapper #'uuid-string-to-octets)))

(define-client-request describe-persona ()
  (uuid)
  (:ok (&single (persona persona)))
  ((:error not-found) (uuid)))

(define-mapping-from-request persona ()
  ((uuid :type string
         :mapper #'uuid-string-to-octets)
   (name :type string)
   (gender :type symbol
           :mapper #'gender-symbol-to-keyword)
   (description :type string)))
Edited
protocol-new.lisp 4.18 KB
  • (define-request hello ()
      (client-type version)
      (:ok (server-type version name &optional (motd "")))
      ((:warning cookie-used-elsewhere) (ip-address)))
    
    (define-request login ()
      (&key email password cookie)
      (:ok (cookie))
      ((:error password-expired) ())
      ((:error invalid-credentials) ())
      ((:error account-banned) (&optional (reason ""))))
    
    (define-request (children gateway) ()
      (&optional page-start page-size)
      (:ok (total-timelines page-start page-size &list (timelines timeline))))
    
    (define-description timeline ()
      ((uuid :type string
             :mapper #'uuid-string-to-octets)
       (name :type string)
       (nposts :type unsigned-byte)
       (nchapters :type unsigned-byte)
       (npersonas :type unsigned-byte)
       (nplayers :type unsigned-byte)
       (type :type symbol
             :mapper #'timeline-symbol-to-keyword)
       (last-modified-timestamp :type unsigned-byte
                                :mapper #'timestamp-unix-to-date)
       (last-modified-persona :type string
                              :mapper #'uuid-string-to-octets)))
    
    (define-request (children timeline) ()
      (uuid &optional page-start page-size)
      (:ok (uuid total-chapters start count &list (chapters chapter)))
      ((:error not-found) (uuid)))
    
    (define-description chapter ()
      ((uuid :type string
             :mapper #'uuid-string-to-octets)
       (name :type string)
       (nposts :type unsigned-byte)
       (npersonas :type unsigned-byte)
       (nplayers :type unsigned-byte)
       (created-timestamp :type unsigned-byte
                          :mapper #'timestamp-unix-to-date)
       (last-modified-timestamp :type unsigned-byte
                                :mapper #'timestamp-unix-to-date)
       (last-modified-persona :type string
                              :mapper #'uuid-string-to-octets)))
    
    (define-request (describe persona) ()
      (uuid)
      (:ok (&single (persona persona)))
      ((:error not-found) (uuid)))
    
    (define-description persona ()
      ((uuid :type string
             :mapper #'uuid-string-to-octets)
       (name :type string)
       (gender :type symbol
               :mapper #'gender-symbol-to-keyword)
       (description :type string)
       (owner-uuid :type string
                   :mapper #'uuid-string-to-octets)
       (borrower-uid :type list
                     :mapper (curry #'mapcar #'uuid-string-to-octets))))
    
    (define-request (children chapter) ()
      (uuid)
      (:ok (uuid total-posts start count &list (posts post)))
      ((:error not-found) (uuid)))
    
    (define-description post ()
      ((uuid :type string
             :mapper #'uuid-string-to-octets)
       (author-persona :type string
                       :mapper #'uuid-string-to-octets)
       (author-player :type string
                      :mapper #'uuid-string-to-octets)
       (content :type string)
       (created-timestamp :type unsigned-byte
                          :mapper #'timestamp-unix-to-date)
       (last-modified-timestamp :type unsigned-byte
                                :mapper #'timestamp-unix-to-date)))
    
    (define-request ())
    
    
    
    
    
    (define-request (hello) ...)
    
    (define-request (login) ...)
    
    (define-request (details gateway) ...)
    
    (define-request (children gateway) ...)
    
    (define-request (details ))
    
    GATEWAY
    TIMELINE
    CHAPTER
    POST
    PLAYER
    PERSONA
    
    HELLO
    LOGIN
    DESCRIBE
    CHILDREN
    
    
    (defgeneric hello ())
    
    (defgeneric login (&key email password cookie))
    
    ;; TYPE must be an EQL specializer pointing at a symbol.
    ;; ID must be a string.
    
    (defgeneric details (type id))
    
    (defgeneric children (type id))
    
    (defgeneric describe (type id))
    
    ;; These are the implementing functions called by the above.
    ;; They must be implemented in a different package.
    
    (defgeneric details (object))
    
    (defgeneric children (object))
    
    (defmethod describe (object)
      (list (details object)
            (children object)))
    
    ((C 0) HELLO "Gateway" "pre-alpha") ;; ((C 0) ACK)
    
    ((C 0) (OK HELLO) "Gateway" "pre-alpha" "Origin" "Welcome to Gateway Origin!") ;; ((C 0) ACK)
    
    ((C 1) LOGIN :EMAIL "aza@dorano.com" :PASSWORD "SuperSecretPassword") ;; ...
    
    ((C 1) (OK LOGIN) "3c287a9377bf0cad2738108b74e7dab") ;; ...
    
    ((C 2) CHILDREN GATEWAY)
    
    ((C 2) (OK CHILDREN)
           (GATEWAY "Origin" 301 0 5
                    ((TIMELINE "066e410872fe11e8adc0fa7ae01bbebc"
                               "Actually This Is Just Casual Chat Here"
                               1836 103 184 35 PUBLIC 1529359662
                               "933e712a927f4374b95caa3bb6ea0412")
                     (TIMELINE "066e36f472fe11e8adc0fa7ae01bbebc"
                               "Lots of Very Good RP"
                               80 6 5 3 PUBLIC 1529328320
                               "453d9b8b2beb42ffbe747c0fe1477615")
                     (TIMELINE "066e3ed872fe11e8adc0fa7ae01bbebc"
                               "Middle Earth And Middle Moon"
                               440 13 40 13 PUBLIC 1529328092
                               "2821e30624894ba0b50917c3ca86d281")
                     (TIMELINE "066e3c3a72fe11e8adc0fa7ae01bbebc"
                               "The Castle of Raptors"
                               16 2 2 2 PRIVATE 1529322511
                               "0dc7bff41c6a40ebbbd04ab63b555506")
                     (TIMELINE "066e3dac72fe11e8adc0fa7ae01bbebc"
                               "Generic Modern RP Timeline"
                               18 2 3 2 PUBLIC 1529319908
                               "8f5b1d876f9949018f007ae7a20e2f3c"))))
    
    ((C 3) CHILDREN TIMELINE "3364f6760e4f4575beee052f4e3a0462")
    
    ((C 3) (OK CHILDREN)
           (TIMELINE "3364f6760e4f4575beee052f4e3a0462" 2 0 2
                     ((CHAPTER "066e422072fe11e8adc0fa7ae01bbebc"
                               "Prologue" 14 2 2 1529322317
                               "df8197ecb5824eb881b3696e6455f6ad")
                      (CHAPTER "066e45f472fe11e8adc0fa7ae01bbebc"
                               "Chapter 1 - First Raptors" 2 2 2 1529322511
                               "0dc7bff41c6a40ebbbd04ab63b555506"))))
    
    ((C 4) DESCRIBE PERSONA "0dc7bff41c6a40ebbbd04ab63b555506")
    
    ((C 4) (OK DESCRIBE)
           (PERSONA "033345b28d1c4639b8cc5db6bc023ad0"
                    "Aza d'Orano" F
                    "Just another raptoress who happens to be a young mage woman."))
    
    ((C 5) CHILDREN CHAPTER "066e422072fe11e8adc0fa7ae01bbebc")
    
    ((C 5) (OK CHILDREN)
           (CHAPTER "066e422072fe11e8adc0fa7ae01bbebc"))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment