;;;; ;;;; Naledi ya Africa ("Star of Africa") is an ncurses-based survival game ;;;; set in Africa. ;;;; ;;;; This file is responsible for connecting to the server. ;;;; ;;;; (c) 2018 Daniel Vedder, MIT license ;;;; (in-package :naledi-ya-africa) (let ((naledi-server NIL)) (defun connect-server (&optional (ip *host*) (port *port*)) "Connect to the specified server" ;;FIXME I need to catch some exceptions here... (setf naledi-server (usocket:socket-connect ip port)) (if naledi-server (notify "Connected to server ~A:~A" ip port) (notify "Connection to server ~A:~A failed." ip port))) (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)) (req (string-from-list request))) (logf 4 "CLIENT: sending request ~S" request) (format servstr "~A~%" req) (finish-output servstr) (usocket:wait-for-input naledi-server) (let ((reply (read-line servstr nil))) ;;XXX do I need to be able to read multiple lines? ;; (do* ((raw-reply (multiple-value-list (read-line servstr nil)) ;; (multiple-value-list (read-line servstr nil))) ;; (reply-line (first raw-reply) (first raw-reply)) ;; (eof (second raw-reply) (second raw-reply)) ;; (reply reply-line (sconc reply reply-line))) ;; ((or eof (null reply-line)) ;;FIXME (logf 4 "CLIENT: received reply.") (if (search "ERROR" reply) (error reply) (read-from-string reply))))) (defun disconnect () "Disconnect from the server" (when naledi-server (usocket:socket-close naledi-server) (setf naledi-server NIL) (notify "Disconnected from server."))))