diff --git a/TODO b/TODO index bed520a..7ce1c0f 100644 --- a/TODO +++ b/TODO @@ -14,11 +14,9 @@ * generate secondary seeds -* split src folder into client/server - * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? -* remove `debugging` calls, introduce logging levels +* provide error handling code (pretty much everywhere) * cleanup util.lisp, dump what I don't need @@ -29,14 +27,14 @@ -> SEVERE +* `terminate` hangs when a player is still logged in + * Game map is not rendered * world thread type error: "The value -1 is not of type unsigned-byte when binding sb-impl::n" -> NON-SEVERE - -* `terminate` hangs when a player is still logged in * Lakes are created -> still an issue? diff --git a/TODO b/TODO index bed520a..7ce1c0f 100644 --- a/TODO +++ b/TODO @@ -14,11 +14,9 @@ * generate secondary seeds -* split src folder into client/server - * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? -* remove `debugging` calls, introduce logging levels +* provide error handling code (pretty much everywhere) * cleanup util.lisp, dump what I don't need @@ -29,14 +27,14 @@ -> SEVERE +* `terminate` hangs when a player is still logged in + * Game map is not rendered * world thread type error: "The value -1 is not of type unsigned-byte when binding sb-impl::n" -> NON-SEVERE - -* `terminate` hangs when a player is still logged in * Lakes are created -> still an issue? diff --git a/client/networking.lisp b/client/networking.lisp index 2c84033..bb61c87 100644 --- a/client/networking.lisp +++ b/client/networking.lisp @@ -18,10 +18,11 @@ (notify "Connected to server ~A:~A" ip port) (notify "Connection to server ~A:~A failed." ip port))) - (defun current-server () naledi-server) ;TODO remove after development + (defun current-server () naledi-server) ;XXX remove after development? (defun query-server (&rest request) "Send a request string to the server and return the answer" + ;;TODO the client should handle errors gracefully! (unless naledi-server ;XXX do this with exceptions (return-from query-server "You are not connected to a server!")) (let ((servstr (usocket:socket-stream naledi-server)) @@ -39,7 +40,9 @@ ;; (reply reply-line (sconc reply reply-line))) ;; ((or eof (null reply-line)) ;;FIXME (logf 4 "CLIENT: received reply ~A" reply) - (read-from-string reply)))) + (if (search "ERROR" reply) + (error reply) + (read-from-string reply))))) (defun disconnect () "Disconnect from the server" diff --git a/TODO b/TODO index bed520a..7ce1c0f 100644 --- a/TODO +++ b/TODO @@ -14,11 +14,9 @@ * generate secondary seeds -* split src folder into client/server - * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? -* remove `debugging` calls, introduce logging levels +* provide error handling code (pretty much everywhere) * cleanup util.lisp, dump what I don't need @@ -29,14 +27,14 @@ -> SEVERE +* `terminate` hangs when a player is still logged in + * Game map is not rendered * world thread type error: "The value -1 is not of type unsigned-byte when binding sb-impl::n" -> NON-SEVERE - -* `terminate` hangs when a player is still logged in * Lakes are created -> still an issue? diff --git a/client/networking.lisp b/client/networking.lisp index 2c84033..bb61c87 100644 --- a/client/networking.lisp +++ b/client/networking.lisp @@ -18,10 +18,11 @@ (notify "Connected to server ~A:~A" ip port) (notify "Connection to server ~A:~A failed." ip port))) - (defun current-server () naledi-server) ;TODO remove after development + (defun current-server () naledi-server) ;XXX remove after development? (defun query-server (&rest request) "Send a request string to the server and return the answer" + ;;TODO the client should handle errors gracefully! (unless naledi-server ;XXX do this with exceptions (return-from query-server "You are not connected to a server!")) (let ((servstr (usocket:socket-stream naledi-server)) @@ -39,7 +40,9 @@ ;; (reply reply-line (sconc reply reply-line))) ;; ((or eof (null reply-line)) ;;FIXME (logf 4 "CLIENT: received reply ~A" reply) - (read-from-string reply)))) + (if (search "ERROR" reply) + (error reply) + (read-from-string reply))))) (defun disconnect () "Disconnect from the server" diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 55964a3..9b9a9fe 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -149,16 +149,21 @@ (defun draw-map (win) "Draw a portion of the game map in an ncurses window" + ;;FIXME request each patch char singly from the server - doing it all + ;; in one batch seems to take too many resources (setf (croatoan:.color-pair win) '(:white :black)) (croatoan:box win) (croatoan:move win 1 1) (let* ((map-width (- (halve (croatoan:.width win) 'floor) 2)) (map-height (1- (croatoan:.height win))) - (submap (query-server "map" map-width map-height))) + ;; It's a bit ugly that I have to do a `read-from-string` here, + ;; but see the server-side function `get-map' for details + (submap (read-from-string + (query-server "map" map-width map-height)))) (dotimes (h map-height) (dotimes (w map-width) (let ((pch (aref submap w h 0)) (pcol (aref submap w h 1))) - (croatoan:add-char win pch :color-pair (list pcol black)) + (croatoan:add-char win pch :color-pair (list pcol :black)) (croatoan:add-char win #\space))) (croatoan:move win (1+ h) 1))) (croatoan:refresh win)) diff --git a/TODO b/TODO index bed520a..7ce1c0f 100644 --- a/TODO +++ b/TODO @@ -14,11 +14,9 @@ * generate secondary seeds -* split src folder into client/server - * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? -* remove `debugging` calls, introduce logging levels +* provide error handling code (pretty much everywhere) * cleanup util.lisp, dump what I don't need @@ -29,14 +27,14 @@ -> SEVERE +* `terminate` hangs when a player is still logged in + * Game map is not rendered * world thread type error: "The value -1 is not of type unsigned-byte when binding sb-impl::n" -> NON-SEVERE - -* `terminate` hangs when a player is still logged in * Lakes are created -> still an issue? diff --git a/client/networking.lisp b/client/networking.lisp index 2c84033..bb61c87 100644 --- a/client/networking.lisp +++ b/client/networking.lisp @@ -18,10 +18,11 @@ (notify "Connected to server ~A:~A" ip port) (notify "Connection to server ~A:~A failed." ip port))) - (defun current-server () naledi-server) ;TODO remove after development + (defun current-server () naledi-server) ;XXX remove after development? (defun query-server (&rest request) "Send a request string to the server and return the answer" + ;;TODO the client should handle errors gracefully! (unless naledi-server ;XXX do this with exceptions (return-from query-server "You are not connected to a server!")) (let ((servstr (usocket:socket-stream naledi-server)) @@ -39,7 +40,9 @@ ;; (reply reply-line (sconc reply reply-line))) ;; ((or eof (null reply-line)) ;;FIXME (logf 4 "CLIENT: received reply ~A" reply) - (read-from-string reply)))) + (if (search "ERROR" reply) + (error reply) + (read-from-string reply))))) (defun disconnect () "Disconnect from the server" diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 55964a3..9b9a9fe 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -149,16 +149,21 @@ (defun draw-map (win) "Draw a portion of the game map in an ncurses window" + ;;FIXME request each patch char singly from the server - doing it all + ;; in one batch seems to take too many resources (setf (croatoan:.color-pair win) '(:white :black)) (croatoan:box win) (croatoan:move win 1 1) (let* ((map-width (- (halve (croatoan:.width win) 'floor) 2)) (map-height (1- (croatoan:.height win))) - (submap (query-server "map" map-width map-height))) + ;; It's a bit ugly that I have to do a `read-from-string` here, + ;; but see the server-side function `get-map' for details + (submap (read-from-string + (query-server "map" map-width map-height)))) (dotimes (h map-height) (dotimes (w map-width) (let ((pch (aref submap w h 0)) (pcol (aref submap w h 1))) - (croatoan:add-char win pch :color-pair (list pcol black)) + (croatoan:add-char win pch :color-pair (list pcol :black)) (croatoan:add-char win #\space))) (croatoan:move win (1+ h) 1))) (croatoan:refresh win)) diff --git a/server/player.lisp b/server/player.lisp index 712738b..02c9655 100644 --- a/server/player.lisp +++ b/server/player.lisp @@ -28,7 +28,7 @@ :initform '((NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0)))) ;;XXX change habitats to (available-biomes)? -> requires load order change - (:default-initargs :habitat T)) + (:default-initargs :habitat T :char #\@ :color :white)) (defmethod update ((h human)) ;;TODO diff --git a/TODO b/TODO index bed520a..7ce1c0f 100644 --- a/TODO +++ b/TODO @@ -14,11 +14,9 @@ * generate secondary seeds -* split src folder into client/server - * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? -* remove `debugging` calls, introduce logging levels +* provide error handling code (pretty much everywhere) * cleanup util.lisp, dump what I don't need @@ -29,14 +27,14 @@ -> SEVERE +* `terminate` hangs when a player is still logged in + * Game map is not rendered * world thread type error: "The value -1 is not of type unsigned-byte when binding sb-impl::n" -> NON-SEVERE - -* `terminate` hangs when a player is still logged in * Lakes are created -> still an issue? diff --git a/client/networking.lisp b/client/networking.lisp index 2c84033..bb61c87 100644 --- a/client/networking.lisp +++ b/client/networking.lisp @@ -18,10 +18,11 @@ (notify "Connected to server ~A:~A" ip port) (notify "Connection to server ~A:~A failed." ip port))) - (defun current-server () naledi-server) ;TODO remove after development + (defun current-server () naledi-server) ;XXX remove after development? (defun query-server (&rest request) "Send a request string to the server and return the answer" + ;;TODO the client should handle errors gracefully! (unless naledi-server ;XXX do this with exceptions (return-from query-server "You are not connected to a server!")) (let ((servstr (usocket:socket-stream naledi-server)) @@ -39,7 +40,9 @@ ;; (reply reply-line (sconc reply reply-line))) ;; ((or eof (null reply-line)) ;;FIXME (logf 4 "CLIENT: received reply ~A" reply) - (read-from-string reply)))) + (if (search "ERROR" reply) + (error reply) + (read-from-string reply))))) (defun disconnect () "Disconnect from the server" diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 55964a3..9b9a9fe 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -149,16 +149,21 @@ (defun draw-map (win) "Draw a portion of the game map in an ncurses window" + ;;FIXME request each patch char singly from the server - doing it all + ;; in one batch seems to take too many resources (setf (croatoan:.color-pair win) '(:white :black)) (croatoan:box win) (croatoan:move win 1 1) (let* ((map-width (- (halve (croatoan:.width win) 'floor) 2)) (map-height (1- (croatoan:.height win))) - (submap (query-server "map" map-width map-height))) + ;; It's a bit ugly that I have to do a `read-from-string` here, + ;; but see the server-side function `get-map' for details + (submap (read-from-string + (query-server "map" map-width map-height)))) (dotimes (h map-height) (dotimes (w map-width) (let ((pch (aref submap w h 0)) (pcol (aref submap w h 1))) - (croatoan:add-char win pch :color-pair (list pcol black)) + (croatoan:add-char win pch :color-pair (list pcol :black)) (croatoan:add-char win #\space))) (croatoan:move win (1+ h) 1))) (croatoan:refresh win)) diff --git a/server/player.lisp b/server/player.lisp index 712738b..02c9655 100644 --- a/server/player.lisp +++ b/server/player.lisp @@ -28,7 +28,7 @@ :initform '((NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0) (NIL 0)))) ;;XXX change habitats to (available-biomes)? -> requires load order change - (:default-initargs :habitat T)) + (:default-initargs :habitat T :char #\@ :color :white)) (defmethod update ((h human)) ;;TODO diff --git a/server/server.lisp b/server/server.lisp index 48fc035..e6ce205 100644 --- a/server/server.lisp +++ b/server/server.lisp @@ -234,6 +234,8 @@ (defun get-map (swidth sheight) "Return a 3d array (x-coord, y-coord, character/colour) of the visible map" + ;;FIXME exhausts the heap?! -> only return one patch char at a time + ;;XXX implement of "field of view" for each player? (let* ((plr (player-human (get-player (thread-player)))) (width (read-from-string swidth)) (height (read-from-string sheight)) @@ -251,9 +253,13 @@ next-col (biome-col (patch-biome p))))) (setf (aref submap w h 0) next-char (aref submap w h 1) next-col)))) - ;;FIXME arrays are pretty-printed with linebreaks, this causes a - ;; client-side error (only expecting one line) - submap)) + ;;XXX Arrays are pretty-printed with linebreaks, this causes a + ;; client-side error (as the client only expects one line). + ;; The following code takes apart such a pretty print and puts it + ;; back together without linebreaks. However, this means that the + ;; server returns a map string enclosed in _two_ quotation marks, + ;; so the client has to perform an additional call to `read-from-string` + (string-from-list (split-string (to-string submap) #\newline) ""))) (defun describe-patch (coords) "Return a list of lines describing the patch at these coordinates."