|
|
@ -2,6 +2,12 @@ |
|
|
|
|
|
|
|
|
|
|
|
(defclass online-game (g:online-game) |
|
|
|
(defclass online-game (g:online-game) |
|
|
|
((lock :initarg :lock :initform (bt:make-lock) :reader online-game-lock) |
|
|
|
((lock :initarg :lock :initform (bt:make-lock) :reader online-game-lock) |
|
|
|
|
|
|
|
(left-player-connection :initarg :left-player-connection |
|
|
|
|
|
|
|
:initform nil |
|
|
|
|
|
|
|
:accessor online-game-left-player-connection) |
|
|
|
|
|
|
|
(right-player-connection :initarg :right-player-connection |
|
|
|
|
|
|
|
:initform nil |
|
|
|
|
|
|
|
:accessor online-game-right-player-connection) |
|
|
|
(connections :initarg :connections :initform nil :accessor online-game-connections))) |
|
|
|
(connections :initarg :connections :initform nil :accessor online-game-connections))) |
|
|
|
|
|
|
|
|
|
|
|
(defparameter *server* nil) |
|
|
|
(defparameter *server* nil) |
|
|
@ -16,9 +22,6 @@ |
|
|
|
(defmacro loop-while-server-running (&body body) |
|
|
|
(defmacro loop-while-server-running (&body body) |
|
|
|
`(loop while *server-running* do (progn ,@body))) |
|
|
|
`(loop while *server-running* do (progn ,@body))) |
|
|
|
|
|
|
|
|
|
|
|
(defun get-time () |
|
|
|
|
|
|
|
(/ (get-internal-real-time) internal-time-units-per-second)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defun send-data-to-client (data client) |
|
|
|
(defun send-data-to-client (data client) |
|
|
|
(let ((stream (usocket:socket-stream client))) |
|
|
|
(let ((stream (usocket:socket-stream client))) |
|
|
|
(when stream |
|
|
|
(when stream |
|
|
@ -35,18 +38,22 @@ |
|
|
|
(state (g:game-state game)) |
|
|
|
(state (g:game-state game)) |
|
|
|
(last-time (g:state-timestamp state))) |
|
|
|
(last-time (g:state-timestamp state))) |
|
|
|
(loop for action in (sort actions '< :key #'g:action-timestamp) |
|
|
|
(loop for action in (sort actions '< :key #'g:action-timestamp) |
|
|
|
do (g:on-update game (- (g:action-timestamp action) last-time)) |
|
|
|
do (g:on-update game (print (float (- (g:action-timestamp action) last-time)))) |
|
|
|
(setf last-time (g:action-timestamp action)) |
|
|
|
(setf last-time (g:action-timestamp action)) |
|
|
|
(g:apply-action action game)) |
|
|
|
(g:apply-action action game)) |
|
|
|
|
|
|
|
|
|
|
|
(let ((current-time (get-time))) |
|
|
|
(let ((current-time (g:get-time))) |
|
|
|
(g:on-update game (- current-time last-time)) |
|
|
|
(g:on-update game (- current-time last-time)) |
|
|
|
(setf (g:state-timestamp state) current-time)) |
|
|
|
(setf (g:state-timestamp state) current-time)) |
|
|
|
|
|
|
|
|
|
|
|
(setf (g:actions game) nil) |
|
|
|
(setf (g:actions game) nil) |
|
|
|
|
|
|
|
|
|
|
|
(loop for con in connections |
|
|
|
(loop for con in connections |
|
|
|
do (send-message-to-client con g:state-updated-message :game-state state))))) |
|
|
|
do (handler-case (send-message-to-client con g:state-updated-message :game-state state) |
|
|
|
|
|
|
|
(t () |
|
|
|
|
|
|
|
(format t "Socket closed???~%") |
|
|
|
|
|
|
|
(close-connection con))) |
|
|
|
|
|
|
|
)))) |
|
|
|
|
|
|
|
|
|
|
|
(defun update-games () |
|
|
|
(defun update-games () |
|
|
|
(loop-while-server-running |
|
|
|
(loop-while-server-running |
|
|
@ -67,8 +74,31 @@ |
|
|
|
|
|
|
|
|
|
|
|
(defun close-connection (connection) |
|
|
|
(defun close-connection (connection) |
|
|
|
(usocket:socket-close connection) |
|
|
|
(usocket:socket-close connection) |
|
|
|
(let ((game (gethash connection *connections*))) |
|
|
|
(let* ((game (gethash connection *connections*)) |
|
|
|
(when game (remhash (g:game-code game) *games*))) |
|
|
|
(state (and game (g:game-state game)))) |
|
|
|
|
|
|
|
(when game |
|
|
|
|
|
|
|
(setf (online-game-connections game) (remove connection (online-game-connections game))) |
|
|
|
|
|
|
|
(cond ((eq (online-game-left-player-connection game) connection) |
|
|
|
|
|
|
|
(setf (online-game-left-player-connection game) nil) |
|
|
|
|
|
|
|
(let ((player (g:state-left-player state))) |
|
|
|
|
|
|
|
(setf (g:state-left-player state) nil) |
|
|
|
|
|
|
|
(when (online-game-right-player-connection game) |
|
|
|
|
|
|
|
(send-message-to-client (online-game-right-player-connection game) |
|
|
|
|
|
|
|
g:player-left-message |
|
|
|
|
|
|
|
:player-name player |
|
|
|
|
|
|
|
:game-state state)))) |
|
|
|
|
|
|
|
((eq (online-game-right-player-connection game) connection) |
|
|
|
|
|
|
|
(setf (online-game-right-player-connection game) nil) |
|
|
|
|
|
|
|
(let ((player (g:state-right-player state))) |
|
|
|
|
|
|
|
(setf (g:state-right-player state) nil) |
|
|
|
|
|
|
|
(when (online-game-left-player-connection game) |
|
|
|
|
|
|
|
(send-message-to-client (online-game-left-player-connection game) |
|
|
|
|
|
|
|
g:player-left-message |
|
|
|
|
|
|
|
:player-name player |
|
|
|
|
|
|
|
:game-state state))))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(unless (online-game-connections game) |
|
|
|
|
|
|
|
(remhash (g:game-code game) *games*)))) |
|
|
|
(remhash connection *connections*)) |
|
|
|
(remhash connection *connections*)) |
|
|
|
|
|
|
|
|
|
|
|
(defun start-server (port) |
|
|
|
(defun start-server (port) |
|
|
@ -106,9 +136,10 @@ |
|
|
|
(defmethod handle-message ((msg g:create-game-message) stream connection) |
|
|
|
(defmethod handle-message ((msg g:create-game-message) stream connection) |
|
|
|
(let ((game (make-instance 'online-game |
|
|
|
(let ((game (make-instance 'online-game |
|
|
|
:state (make-instance 'g:state |
|
|
|
:state (make-instance 'g:state |
|
|
|
:left-player (g:player-name msg))))) |
|
|
|
:left-player (g:player-name msg)) |
|
|
|
|
|
|
|
:connections (list connection) |
|
|
|
|
|
|
|
:left-player-connection connection))) |
|
|
|
(setf (gethash (g:game-code game) *games*) game) |
|
|
|
(setf (gethash (g:game-code game) *games*) game) |
|
|
|
(pushnew connection (online-game-connections game)) |
|
|
|
|
|
|
|
(setf (gethash connection *connections*) game) |
|
|
|
(setf (gethash connection *connections*) game) |
|
|
|
(let ((response (make-instance 'g:game-created-message |
|
|
|
(let ((response (make-instance 'g:game-created-message |
|
|
|
:game-code (g:game-code game) |
|
|
|
:game-code (g:game-code game) |
|
|
@ -118,24 +149,37 @@ |
|
|
|
(force-output stream))) |
|
|
|
(force-output stream))) |
|
|
|
|
|
|
|
|
|
|
|
(defmethod handle-message ((msg g:join-game-message) stream connection) |
|
|
|
(defmethod handle-message ((msg g:join-game-message) stream connection) |
|
|
|
(let* ((game (gethash (g:game-code msg) *games*)) |
|
|
|
(let ((game (gethash (g:game-code msg) *games*))) |
|
|
|
(state (g:game-state game)) |
|
|
|
(if game |
|
|
|
(left-player (g:state-left-player state)) |
|
|
|
(let ((left-player (g:state-left-player (g:game-state game))) |
|
|
|
(right-player (g:state-right-player state)) |
|
|
|
(right-player (g:state-right-player (g:game-state game)))) |
|
|
|
(paddle (cond (left-player :right) (right-player :left))) |
|
|
|
(if (or (not left-player) (not right-player)) |
|
|
|
(player (g:player-name msg))) |
|
|
|
(let ((paddle (cond (left-player :right) (right-player :left))) |
|
|
|
(when (or (not left-player) (not right-player)) |
|
|
|
(player (g:player-name msg))) |
|
|
|
(pushnew connection (online-game-connections game)) |
|
|
|
(pushnew connection (online-game-connections game)) |
|
|
|
|
|
|
|
(setf (gethash connection *connections*) game) |
|
|
|
(case paddle |
|
|
|
|
|
|
|
(:left (setf (g:state-left-player state) player)) |
|
|
|
(case paddle |
|
|
|
(:right (setf (g:state-right-player state) player))) |
|
|
|
(:left |
|
|
|
|
|
|
|
(setf (g:state-left-player (g:game-state game)) player) |
|
|
|
(let ((response (make-instance 'g:game-joined-message |
|
|
|
(setf (online-game-left-player-connection game) connection)) |
|
|
|
:player-paddle paddle |
|
|
|
(:right |
|
|
|
:game-state state))) |
|
|
|
(setf (g:state-right-player (g:game-state game)) player) |
|
|
|
(loop for con in (online-game-connections game) |
|
|
|
(setf (online-game-right-player-connection game) connection))) |
|
|
|
do (send-data-to-client response con)))))) |
|
|
|
|
|
|
|
|
|
|
|
(setf (g:game-state game) |
|
|
|
|
|
|
|
(make-instance 'g:state |
|
|
|
|
|
|
|
:left-player (g:state-left-player (g:game-state game)) |
|
|
|
|
|
|
|
:right-player (g:state-right-player (g:game-state game)))) |
|
|
|
|
|
|
|
(g:random-launch-ball (g:game-state game)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(let ((response (make-instance 'g:game-joined-message |
|
|
|
|
|
|
|
:player-paddle paddle |
|
|
|
|
|
|
|
:game-state (g:game-state game)))) |
|
|
|
|
|
|
|
(loop for con in (online-game-connections game) |
|
|
|
|
|
|
|
do (send-data-to-client response con)))) |
|
|
|
|
|
|
|
(send-message-to-client connection g:game-full))) |
|
|
|
|
|
|
|
(send-message-to-client connection g:game-does-not-exist)))) |
|
|
|
|
|
|
|
|
|
|
|
;; (start-server 54321) |
|
|
|
;; (start-server 54321) |
|
|
|
;; (stop-server) |
|
|
|
;; (stop-server) |
|
|
|