Update API

This commit is contained in:
Loic Guegan 2019-05-10 08:51:16 +02:00
parent 409897562c
commit b35687d51b
3 changed files with 17 additions and 34 deletions

View file

@ -4,8 +4,14 @@
#+LATEX_HEADER: \usepackage{fullpage} #+LATEX_HEADER: \usepackage{fullpage}
* General Description * General Description
- All transmissions will be based on UDP - All transmissions will be based on TCP because:
- All UDP packet will contain plain json data - Packet length are not fixed
- Packet ordering is important
- All TCP stream from *client to server* will:
- Contain plain json data
- Be terminated by a "#EOF" line (in order for the server to detect the end of the request
- All TCP stream from *server to client* will contains plai json data (connection will be closed by the server
so there is no need of "#EOF".
* Communications * Communications
** Initialisation ** Initialisation
1. Server wait for a client 1. Server wait for a client
@ -14,36 +20,33 @@
{ {
"type": "new-game" "type": "new-game"
} }
#EOF
#+END_SRC #+END_SRC
3. Server can reply: 3. Server can reply:
#+BEGIN_SRC json #+BEGIN_SRC json
{ {
"type": "state", "type": "state",
"syn": 1,
"game-id": 1, "game-id": 1,
"game-over": false, "game-over": false,
"snake": [[1,2],[1,3]], "snake": [[1,2],[1,3]],
"food": [[6,7]] "food": [[6,7]]
} }
#+END_SRC #+END_SRC
Note that, syn entry is used to keep packet ordering consistent and detecting packet inversion on the network. Thus,
syn entry indicate the expected syn that the client should send on the next UDP packet.
** Gameplay ** Gameplay
*** Change Direction *** Change Direction
1. When client is playing a game it can ask to the server to change snake direction: 1. When client is playing a game it can ask to the server to change snake direction:
#+BEGIN_SRC json #+BEGIN_SRC json
{ {
"type": "update", "type": "update",
"syn": 1,
"game-id": 1, "game-id": 1,
"direction": "left", "direction": "left",
} }
#EOF
#+END_SRC #+END_SRC
2. Server can reply 2. Server can reply
#+BEGIN_SRC json #+BEGIN_SRC json
{ {
"type": "state", "type": "state",
"syn": 2,
"game-id": 1, "game-id": 1,
"game-over": false, "game-over": false,
"snake": [[0,2],[1,2]], "snake": [[0,2],[1,2]],
@ -55,16 +58,15 @@
#+BEGIN_SRC json #+BEGIN_SRC json
{ {
"type": "update", "type": "update",
"syn": 2,
"game-id": 1, "game-id": 1,
"direction": null "direction": null
} }
#EOF
#+END_SRC #+END_SRC
2. Server can reply: 2. Server can reply:
#+BEGIN_SRC json #+BEGIN_SRC json
{ {
"type": "state", "type": "state",
"syn": 3,
"game-id": 1, "game-id": 1,
"game-over": false, "game-over": false,
"snake": [[1,2],[0,2]], "snake": [[1,2],[0,2]],
@ -76,11 +78,10 @@
#+BEGIN_SRC json #+BEGIN_SRC json
{ {
"type": "state", "type": "state",
"syn": null,
"game-id": 1, "game-id": 1,
"game-over": true, "game-over": true,
"snake": [[0,2],[1,2]], "snake": [[0,2],[1,2]],
"food": [[6,7]] "food": [[6,7]]
} }
#+END_SRC #+END_SRC
- No reply is expected from the client and server will be in charge to free local memory. Note that syn=null. - No reply is expected from the client and server will be in charge to free local memory.

Binary file not shown.

View file

@ -4,25 +4,7 @@
(defclass api () (defclass api ()
((gm ((gm
:initform (make-instance 'game-manager)) :initform (make-instance 'game-manager))))
(games-syn
:initform '())))
(defmethod create-syn ((api api) game-id &optional (initial-value 0))
(unless (eq nil (get-syn api game-id)) (error "This game ~a already have a syn !" game-id))
(with-slots (games-syn) api
(push (list :game-id game-id :syn initial-value) games-syn)
initial-value))
(defmethod refresh-syn ((api api) game-id)
(with-slots (games-syn) api
(incf (getf (first (remove-if-not #'(lambda (entry) (eql game-id (getf entry :game-id))) games-syn)) :syn))))
(defmethod get-syn ((api api) game-id)
(with-slots (games-syn) api
(getf (first (remove-if-not #'(lambda (entry) (eql game-id (getf entry :game-id))) games-syn)) :syn)))
;;; TODO: Handle errors (valid json etc..) ;;; TODO: Handle errors (valid json etc..)
@ -34,12 +16,11 @@
(defmethod handle-new-game ((api api) data) (defmethod handle-new-game ((api api) data)
(with-slots (gm) api (with-slots (gm) api
(let* ((game-id (create-game gm)) (let* ((game-id (create-game gm)))
(game-syn (create-syn api game-id 1))) ; Create syn with 1 (since first packet already receive)
(let ((game-dump (dump gm game-id))) (let ((game-dump (dump gm game-id)))
(setf (getf game-dump :game-over) :null) ; Define nil as null (for json) (setf (getf game-dump :game-over) :null) ; Define nil as null (for json)
(to-json (to-json
(append (list :type "state" :syn game-syn) game-dump)))))) (append (list :type "state") game-dump))))))
;;; TODO: RETURN JSON !!!! ;;; TODO: RETURN JSON !!!!
(defmethod handle-update ((api api) data) (defmethod handle-update ((api api) data)
@ -55,7 +36,8 @@
(t (setf dir nil))) (t (setf dir nil)))
(if dir (if dir
(refresh game :dir dir) (refresh game :dir dir)
(refresh game))))) (refresh game))
(append (list :type "update") (dump gm game-id)))))