diff --git a/TODO b/TODO index dbd2986..8039cc5 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,8 @@ GAME * UI: enable remote game joining - + -> implement `inform-user` + * implement look/walk/attack modes * expand player implementation diff --git a/TODO b/TODO index dbd2986..8039cc5 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,8 @@ GAME * UI: enable remote game joining - + -> implement `inform-user` + * implement look/walk/attack modes * expand player implementation diff --git a/client/crt-ext.lisp b/client/crt-ext.lisp index 187a864..077e376 100644 --- a/client/crt-ext.lisp +++ b/client/crt-ext.lisp @@ -67,7 +67,7 @@ (croatoan:draw-menu dw)) (#\newline (return-from croatoan:event-case - (equalp (croatoan:.current-item dw) " Yes")))))) + (zerop (croatoan:.current-item-number dw))))))) (defun inform-user (scr msg) "Display an informational message to the user" diff --git a/TODO b/TODO index dbd2986..8039cc5 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,8 @@ GAME * UI: enable remote game joining - + -> implement `inform-user` + * implement look/walk/attack modes * expand player implementation diff --git a/client/crt-ext.lisp b/client/crt-ext.lisp index 187a864..077e376 100644 --- a/client/crt-ext.lisp +++ b/client/crt-ext.lisp @@ -67,7 +67,7 @@ (croatoan:draw-menu dw)) (#\newline (return-from croatoan:event-case - (equalp (croatoan:.current-item dw) " Yes")))))) + (zerop (croatoan:.current-item-number dw))))))) (defun inform-user (scr msg) "Display an informational message to the user" diff --git a/client/networking.lisp b/client/networking.lisp index a920e99..aa89563 100644 --- a/client/networking.lisp +++ b/client/networking.lisp @@ -22,19 +22,25 @@ (defun query-server (&rest request) "Send a request string to the server and return the answer" + ;; If one argument is :ignore-errors, error strings are passed up + ;; to the caller. Otherwise, they cause a crash. ;;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)) - (req (string-from-list request))) + (let* ((servstr (usocket:socket-stream naledi-server)) + (ig-errors (find ':ignore-errors request)) + (req (string-from-list + (remove-if #'(lambda (s) (eq s ':ignore-errors)) + request)))) (logf 4 "CLIENT: sending request ~S" request) (format servstr "~A~%" req) (finish-output servstr) (usocket:wait-for-input naledi-server) (let ((reply (read servstr nil))) (logf 4 "CLIENT: received reply.") - (if (search "ERROR" reply) - (error reply) reply)))) + (when (search "ERROR" reply) + (if ig-errors (logf 1 reply) (error reply))) + reply))) (defun disconnect () "Disconnect from the server" diff --git a/TODO b/TODO index dbd2986..8039cc5 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,8 @@ GAME * UI: enable remote game joining - + -> implement `inform-user` + * implement look/walk/attack modes * expand player implementation diff --git a/client/crt-ext.lisp b/client/crt-ext.lisp index 187a864..077e376 100644 --- a/client/crt-ext.lisp +++ b/client/crt-ext.lisp @@ -67,7 +67,7 @@ (croatoan:draw-menu dw)) (#\newline (return-from croatoan:event-case - (equalp (croatoan:.current-item dw) " Yes")))))) + (zerop (croatoan:.current-item-number dw))))))) (defun inform-user (scr msg) "Display an informational message to the user" diff --git a/client/networking.lisp b/client/networking.lisp index a920e99..aa89563 100644 --- a/client/networking.lisp +++ b/client/networking.lisp @@ -22,19 +22,25 @@ (defun query-server (&rest request) "Send a request string to the server and return the answer" + ;; If one argument is :ignore-errors, error strings are passed up + ;; to the caller. Otherwise, they cause a crash. ;;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)) - (req (string-from-list request))) + (let* ((servstr (usocket:socket-stream naledi-server)) + (ig-errors (find ':ignore-errors request)) + (req (string-from-list + (remove-if #'(lambda (s) (eq s ':ignore-errors)) + request)))) (logf 4 "CLIENT: sending request ~S" request) (format servstr "~A~%" req) (finish-output servstr) (usocket:wait-for-input naledi-server) (let ((reply (read servstr nil))) (logf 4 "CLIENT: received reply.") - (if (search "ERROR" reply) - (error reply) reply)))) + (when (search "ERROR" reply) + (if ig-errors (logf 1 reply) (error reply))) + reply))) (defun disconnect () "Disconnect from the server" diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 30b36ca..0dcfd95 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -116,12 +116,22 @@ (query-user scr "Server port:" :default (second *defaulthost*) :cls T))) (if (user-confirm-p scr (format nil "Connect to ~A:~S?" *host* *port*) T) - ;;TODO ask for username/password! - ;;(login-or-signup scr) - (connect-server) + (progn (connect-server) + (login-or-signup scr)) (start-or-connect-to-server scr))) -;;TODO (defun login-or-signup (scr)) +(defun login-or-signup (scr) + "Ask for username/password and log the user in" + (let* ((uname (query-user scr "User name:" :cls T)) + (upass (query-user scr "Password:" :cls T)) + (reply (query-server "login" uname upass ':ignore-errors))) + (cond ((search "bad password" reply) + (inform-user scr "Bad password!") ;;TODO Not yet implemented! + (start-or-connect-to-server scr)) + ((search "nonexistent player" reply) + (if (user-confirm-p scr "This player doesn't exist. Create?" T) + (query-server "signup" uname upass) + (start-or-connect-to-server scr)))))) (defun user-interface (scr) "Create the screen on the ncurses interface and hand over to window functions" diff --git a/TODO b/TODO index dbd2986..8039cc5 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,8 @@ GAME * UI: enable remote game joining - + -> implement `inform-user` + * implement look/walk/attack modes * expand player implementation diff --git a/client/crt-ext.lisp b/client/crt-ext.lisp index 187a864..077e376 100644 --- a/client/crt-ext.lisp +++ b/client/crt-ext.lisp @@ -67,7 +67,7 @@ (croatoan:draw-menu dw)) (#\newline (return-from croatoan:event-case - (equalp (croatoan:.current-item dw) " Yes")))))) + (zerop (croatoan:.current-item-number dw))))))) (defun inform-user (scr msg) "Display an informational message to the user" diff --git a/client/networking.lisp b/client/networking.lisp index a920e99..aa89563 100644 --- a/client/networking.lisp +++ b/client/networking.lisp @@ -22,19 +22,25 @@ (defun query-server (&rest request) "Send a request string to the server and return the answer" + ;; If one argument is :ignore-errors, error strings are passed up + ;; to the caller. Otherwise, they cause a crash. ;;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)) - (req (string-from-list request))) + (let* ((servstr (usocket:socket-stream naledi-server)) + (ig-errors (find ':ignore-errors request)) + (req (string-from-list + (remove-if #'(lambda (s) (eq s ':ignore-errors)) + request)))) (logf 4 "CLIENT: sending request ~S" request) (format servstr "~A~%" req) (finish-output servstr) (usocket:wait-for-input naledi-server) (let ((reply (read servstr nil))) (logf 4 "CLIENT: received reply.") - (if (search "ERROR" reply) - (error reply) reply)))) + (when (search "ERROR" reply) + (if ig-errors (logf 1 reply) (error reply))) + reply))) (defun disconnect () "Disconnect from the server" diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 30b36ca..0dcfd95 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -116,12 +116,22 @@ (query-user scr "Server port:" :default (second *defaulthost*) :cls T))) (if (user-confirm-p scr (format nil "Connect to ~A:~S?" *host* *port*) T) - ;;TODO ask for username/password! - ;;(login-or-signup scr) - (connect-server) + (progn (connect-server) + (login-or-signup scr)) (start-or-connect-to-server scr))) -;;TODO (defun login-or-signup (scr)) +(defun login-or-signup (scr) + "Ask for username/password and log the user in" + (let* ((uname (query-user scr "User name:" :cls T)) + (upass (query-user scr "Password:" :cls T)) + (reply (query-server "login" uname upass ':ignore-errors))) + (cond ((search "bad password" reply) + (inform-user scr "Bad password!") ;;TODO Not yet implemented! + (start-or-connect-to-server scr)) + ((search "nonexistent player" reply) + (if (user-confirm-p scr "This player doesn't exist. Create?" T) + (query-server "signup" uname upass) + (start-or-connect-to-server scr)))))) (defun user-interface (scr) "Create the screen on the ncurses interface and hand over to window functions" diff --git a/params.lisp b/params.lisp index 3b1f3fa..fc36dc7 100644 --- a/params.lisp +++ b/params.lisp @@ -28,7 +28,7 @@ (defparameter *framerate* 1000) ;;Localhost defaults -(defparameter *defaulthost* '("127.0.0.1" 21895)) ;default port: 21895 +(defparameter *defaulthost* '("127.0.0.1" 21887)) ;default port: 21895 ;;Host server address to connect to - XXX global variable! (defparameter *host* (first *defaulthost*)) diff --git a/TODO b/TODO index dbd2986..8039cc5 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,8 @@ GAME * UI: enable remote game joining - + -> implement `inform-user` + * implement look/walk/attack modes * expand player implementation diff --git a/client/crt-ext.lisp b/client/crt-ext.lisp index 187a864..077e376 100644 --- a/client/crt-ext.lisp +++ b/client/crt-ext.lisp @@ -67,7 +67,7 @@ (croatoan:draw-menu dw)) (#\newline (return-from croatoan:event-case - (equalp (croatoan:.current-item dw) " Yes")))))) + (zerop (croatoan:.current-item-number dw))))))) (defun inform-user (scr msg) "Display an informational message to the user" diff --git a/client/networking.lisp b/client/networking.lisp index a920e99..aa89563 100644 --- a/client/networking.lisp +++ b/client/networking.lisp @@ -22,19 +22,25 @@ (defun query-server (&rest request) "Send a request string to the server and return the answer" + ;; If one argument is :ignore-errors, error strings are passed up + ;; to the caller. Otherwise, they cause a crash. ;;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)) - (req (string-from-list request))) + (let* ((servstr (usocket:socket-stream naledi-server)) + (ig-errors (find ':ignore-errors request)) + (req (string-from-list + (remove-if #'(lambda (s) (eq s ':ignore-errors)) + request)))) (logf 4 "CLIENT: sending request ~S" request) (format servstr "~A~%" req) (finish-output servstr) (usocket:wait-for-input naledi-server) (let ((reply (read servstr nil))) (logf 4 "CLIENT: received reply.") - (if (search "ERROR" reply) - (error reply) reply)))) + (when (search "ERROR" reply) + (if ig-errors (logf 1 reply) (error reply))) + reply))) (defun disconnect () "Disconnect from the server" diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 30b36ca..0dcfd95 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -116,12 +116,22 @@ (query-user scr "Server port:" :default (second *defaulthost*) :cls T))) (if (user-confirm-p scr (format nil "Connect to ~A:~S?" *host* *port*) T) - ;;TODO ask for username/password! - ;;(login-or-signup scr) - (connect-server) + (progn (connect-server) + (login-or-signup scr)) (start-or-connect-to-server scr))) -;;TODO (defun login-or-signup (scr)) +(defun login-or-signup (scr) + "Ask for username/password and log the user in" + (let* ((uname (query-user scr "User name:" :cls T)) + (upass (query-user scr "Password:" :cls T)) + (reply (query-server "login" uname upass ':ignore-errors))) + (cond ((search "bad password" reply) + (inform-user scr "Bad password!") ;;TODO Not yet implemented! + (start-or-connect-to-server scr)) + ((search "nonexistent player" reply) + (if (user-confirm-p scr "This player doesn't exist. Create?" T) + (query-server "signup" uname upass) + (start-or-connect-to-server scr)))))) (defun user-interface (scr) "Create the screen on the ncurses interface and hand over to window functions" diff --git a/params.lisp b/params.lisp index 3b1f3fa..fc36dc7 100644 --- a/params.lisp +++ b/params.lisp @@ -28,7 +28,7 @@ (defparameter *framerate* 1000) ;;Localhost defaults -(defparameter *defaulthost* '("127.0.0.1" 21895)) ;default port: 21895 +(defparameter *defaulthost* '("127.0.0.1" 21887)) ;default port: 21895 ;;Host server address to connect to - XXX global variable! (defparameter *host* (first *defaulthost*)) diff --git a/util.lisp b/util.lisp index 751fc53..1fc6db9 100644 --- a/util.lisp +++ b/util.lisp @@ -74,7 +74,6 @@ ;; Some of these functions are probably quite inefficient (lots of consing) (defun remove-first-if (fn lst) - ;;FIXME isn't this identical to `remove-if'? "Remove the first element in a list that satisfies the given predicate" (cond ((null lst) NIL) ((funcall fn (car lst)) (cdr lst))