fix communication
This commit is contained in:
parent
65e0c5d272
commit
ab4a2a4130
6 changed files with 76 additions and 89 deletions
|
@ -20,12 +20,8 @@ import Data.IORef
|
||||||
|
|
||||||
import Data.UUID
|
import Data.UUID
|
||||||
|
|
||||||
import qualified Data.Vector.Storable as VS
|
|
||||||
|
|
||||||
import Foreign hiding (void)
|
import Foreign hiding (void)
|
||||||
|
|
||||||
import Graphics.Vty as Vty
|
|
||||||
|
|
||||||
import Network.Socket
|
import Network.Socket
|
||||||
|
|
||||||
import System.Posix.Signals
|
import System.Posix.Signals
|
||||||
|
@ -46,11 +42,10 @@ connectSocket path = do
|
||||||
|
|
||||||
-- | Sends a specified message through given socket to the server
|
-- | Sends a specified message through given socket to the server
|
||||||
sendMessage
|
sendMessage
|
||||||
:: StateContainer
|
:: ClientMessage
|
||||||
-> ClientMessage
|
|
||||||
-> Socket
|
-> Socket
|
||||||
-> IO ()
|
-> IO ()
|
||||||
sendMessage st msg sock = do
|
sendMessage msg sock = do
|
||||||
let msgJson = A.encode msg
|
let msgJson = A.encode msg
|
||||||
msgList = B.unpack $ B.toStrict msgJson
|
msgList = B.unpack $ B.toStrict msgJson
|
||||||
ptr <- newArray msgList
|
ptr <- newArray msgList
|
||||||
|
@ -79,9 +74,7 @@ handleMessage ServerQuit = do
|
||||||
handleMessage (Ping id') = do
|
handleMessage (Ping id') = do
|
||||||
cid <- asks rcClientUUID
|
cid <- asks rcClientUUID
|
||||||
sock <- asks rcSocket
|
sock <- asks rcSocket
|
||||||
st <- get
|
|
||||||
liftIO $ sendMessage
|
liftIO $ sendMessage
|
||||||
st
|
|
||||||
( ClientMessage
|
( ClientMessage
|
||||||
cid
|
cid
|
||||||
(Pong id')
|
(Pong id')
|
||||||
|
@ -106,12 +99,7 @@ gracefulExit
|
||||||
-> IO ()
|
-> IO ()
|
||||||
gracefulExit st reason = do
|
gracefulExit st reason = do
|
||||||
liftIO $ putStrLn reason
|
liftIO $ putStrLn reason
|
||||||
let stateCont = scClientState st
|
writeIORef (scStopper st) True
|
||||||
liftIO $ STM.atomically $ do
|
|
||||||
stateContainer <- STM.readTMVar stateCont
|
|
||||||
void $ STM.swapTMVar stateCont $ stateContainer
|
|
||||||
{ clientStop = True
|
|
||||||
}
|
|
||||||
|
|
||||||
receiveMessage
|
receiveMessage
|
||||||
:: Socket
|
:: Socket
|
||||||
|
@ -148,10 +136,12 @@ terminateGameOnSigint
|
||||||
:: IORef Bool
|
:: IORef Bool
|
||||||
-> Game ()
|
-> Game ()
|
||||||
terminateGameOnSigint stopper = do
|
terminateGameOnSigint stopper = do
|
||||||
|
rc <- ask
|
||||||
void $ liftIO $ installHandler
|
void $ liftIO $ installHandler
|
||||||
keyboardSignal
|
keyboardSignal
|
||||||
(CatchOnce $ do
|
(CatchOnce $ do
|
||||||
putStrLn "receiveMessage: SIGINT caught, terminating…"
|
putStrLn "receiveMessage: SIGINT caught, terminating…"
|
||||||
|
liftIO $ partingMessage (rcClientUUID rc) (rcSocket rc)
|
||||||
atomicWriteIORef stopper True
|
atomicWriteIORef stopper True
|
||||||
-- Vty.shutdown (clientVty currentState)
|
-- Vty.shutdown (clientVty currentState)
|
||||||
-- Raise SIGINT again so it does not get blocked
|
-- Raise SIGINT again so it does not get blocked
|
||||||
|
@ -160,10 +150,9 @@ terminateGameOnSigint stopper = do
|
||||||
Nothing
|
Nothing
|
||||||
|
|
||||||
partingMessage
|
partingMessage
|
||||||
:: StateContainer
|
:: UUID
|
||||||
-> UUID
|
|
||||||
-> Socket
|
-> Socket
|
||||||
-> IO ()
|
-> IO ()
|
||||||
partingMessage st clientId sock = do
|
partingMessage clientId sock = do
|
||||||
sendMessage st (ClientMessage clientId ClientQuit) sock
|
putStrLn "sending parting message to server…"
|
||||||
-- close sock
|
sendMessage (ClientMessage clientId ClientQuit) sock
|
||||||
|
|
|
@ -1,16 +1,10 @@
|
||||||
module Client.Game where
|
module Client.Game where
|
||||||
|
|
||||||
import Control.Concurrent
|
|
||||||
|
|
||||||
import qualified Control.Concurrent.STM as STM
|
|
||||||
|
|
||||||
import Control.Monad
|
|
||||||
|
|
||||||
import Control.Monad.Loops
|
import Control.Monad.Loops
|
||||||
|
|
||||||
import Control.Monad.RWS
|
import Control.Monad.RWS
|
||||||
|
|
||||||
import Data.IORef (IORef, readIORef)
|
import Data.IORef (readIORef)
|
||||||
|
|
||||||
import Graphics.Vty
|
import Graphics.Vty
|
||||||
|
|
||||||
|
@ -23,23 +17,21 @@ import Client.Types
|
||||||
import Library.Types
|
import Library.Types
|
||||||
|
|
||||||
runGame
|
runGame
|
||||||
:: IORef Bool
|
:: Game ()
|
||||||
-> Game ()
|
runGame = do
|
||||||
runGame stopper = do
|
|
||||||
sock <- asks rcSocket
|
sock <- asks rcSocket
|
||||||
queue <- asks rcQueue
|
queue <- asks rcQueue
|
||||||
clientId <- asks rcClientUUID
|
clientId <- asks rcClientUUID
|
||||||
st <- get
|
st <- get
|
||||||
-- recvThread <- liftIO $ forkIO $ forever $ receiveMessage sock queue st
|
-- recvThread <- liftIO $ forkIO $ forever $ receiveMessage sock queue st
|
||||||
liftIO $ sendMessage st(ClientMessage clientId ClientReady) sock
|
liftIO $ sendMessage (ClientMessage clientId ClientReady) sock
|
||||||
whileM_
|
whileM_
|
||||||
(liftIO (not <$> readIORef stopper))
|
(liftIO (not <$> readIORef (scStopper st)))
|
||||||
(do
|
(do
|
||||||
liftIO $ receiveMessage sock queue st
|
liftIO $ receiveMessage sock queue st
|
||||||
handleMessages
|
handleMessages
|
||||||
-- draw
|
-- draw
|
||||||
)
|
)
|
||||||
liftIO $ partingMessage st clientId sock
|
|
||||||
-- liftIO $ killThread recvThread
|
-- liftIO $ killThread recvThread
|
||||||
|
|
||||||
handleEvent
|
handleEvent
|
||||||
|
|
|
@ -6,6 +6,8 @@ import Control.Exception (Exception)
|
||||||
|
|
||||||
import Control.Monad.RWS
|
import Control.Monad.RWS
|
||||||
|
|
||||||
|
import Data.IORef (IORef)
|
||||||
|
|
||||||
import Data.UUID
|
import Data.UUID
|
||||||
|
|
||||||
import Network.Socket
|
import Network.Socket
|
||||||
|
@ -37,6 +39,7 @@ data StateContainer = StateContainer
|
||||||
{ scWizard :: Wizard
|
{ scWizard :: Wizard
|
||||||
, scClientState :: STM.TMVar ClientState
|
, scClientState :: STM.TMVar ClientState
|
||||||
, scMapSlice :: MapSlice
|
, scMapSlice :: MapSlice
|
||||||
|
, scStopper :: IORef Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Game = RWST ReaderContainer String StateContainer IO
|
type Game = RWST ReaderContainer String StateContainer IO
|
||||||
|
|
|
@ -14,8 +14,6 @@ import qualified Data.Matrix as M
|
||||||
|
|
||||||
import Graphics.Vty
|
import Graphics.Vty
|
||||||
|
|
||||||
import Network.Socket (close)
|
|
||||||
|
|
||||||
import Options.Applicative
|
import Options.Applicative
|
||||||
|
|
||||||
-- internal imports
|
-- internal imports
|
||||||
|
@ -39,9 +37,9 @@ main = do
|
||||||
|
|
||||||
|
|
||||||
-- threadDelay $ 1 * 10 ^ 6
|
-- threadDelay $ 1 * 10 ^ 6
|
||||||
mockClientState <- STM.newTMVarIO (ClientState undefined False False)
|
mockClientState <- STM.newTMVarIO (ClientState undefined False)
|
||||||
let mockState = StateContainer undefined mockClientState undefined
|
let mockState = StateContainer undefined mockClientState undefined undefined
|
||||||
sendMessage mockState (IdRequest) sock
|
sendMessage IdRequest sock
|
||||||
receiveMessage sock queue mockState
|
receiveMessage sock queue mockState
|
||||||
awaitResponse queue 1
|
awaitResponse queue 1
|
||||||
clientIdMsg <- head <$> STM.atomically (STM.flushTQueue queue)
|
clientIdMsg <- head <$> STM.atomically (STM.flushTQueue queue)
|
||||||
|
@ -53,7 +51,7 @@ main = do
|
||||||
threadDelay $ 5 * 10 ^ 6
|
threadDelay $ 5 * 10 ^ 6
|
||||||
|
|
||||||
|
|
||||||
sendMessage mockState (ClientMessage clientId ClientRequestWizard) sock
|
sendMessage (ClientMessage clientId ClientRequestWizard) sock
|
||||||
-- threadDelay $ 1 * 10 ^ 6
|
-- threadDelay $ 1 * 10 ^ 6
|
||||||
receiveMessage sock queue mockState
|
receiveMessage sock queue mockState
|
||||||
awaitResponse queue 1
|
awaitResponse queue 1
|
||||||
|
@ -67,17 +65,17 @@ main = do
|
||||||
-- shut down graphical interface for now
|
-- shut down graphical interface for now
|
||||||
-- shutdown vty
|
-- shutdown vty
|
||||||
|
|
||||||
clientState <- STM.newTMVarIO (ClientState undefined False False)
|
stopper <- newIORef False
|
||||||
|
clientState <- STM.newTMVarIO (ClientState undefined False)
|
||||||
let initSlice = MapSlice (M.matrix 9 9 (const Nothing)) []
|
let initSlice = MapSlice (M.matrix 9 9 (const Nothing)) []
|
||||||
let initRead = ReaderContainer sock clientId queue
|
let initRead = ReaderContainer sock clientId queue
|
||||||
initState = StateContainer (initWizard playerWizard) clientState initSlice
|
initState = StateContainer (initWizard playerWizard) clientState initSlice stopper
|
||||||
-- putStrLn "sending quit message"
|
-- putStrLn "sending quit message"
|
||||||
-- sendMessage (ClientMessage clientId ClientQuit) sock
|
-- sendMessage (ClientMessage clientId ClientQuit) sock
|
||||||
stopper <- newIORef False
|
|
||||||
void $ execRWST
|
void $ execRWST
|
||||||
(do
|
(do
|
||||||
terminateGameOnSigint stopper
|
terminateGameOnSigint stopper
|
||||||
runGame stopper
|
runGame
|
||||||
)
|
)
|
||||||
initRead
|
initRead
|
||||||
initState
|
initState
|
||||||
|
|
|
@ -16,7 +16,6 @@ import Data.Aeson (ToJSON, FromJSON)
|
||||||
data ClientState = ClientState
|
data ClientState = ClientState
|
||||||
{ clientVty :: Vty -- ^ Context object for graphics
|
{ clientVty :: Vty -- ^ Context object for graphics
|
||||||
, clientGameOver :: Bool -- ^ client game over (contestant died)
|
, clientGameOver :: Bool -- ^ client game over (contestant died)
|
||||||
, clientStop :: Bool -- ^ client shutdown
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Type synonym for the Map. Translates to a Matrix of 'Tile's
|
-- | Type synonym for the Map. Translates to a Matrix of 'Tile's
|
||||||
|
|
|
@ -62,13 +62,13 @@ terminateGameOnSigint
|
||||||
:: Game ()
|
:: Game ()
|
||||||
terminateGameOnSigint = do
|
terminateGameOnSigint = do
|
||||||
sock <- asks rcMainSocket
|
sock <- asks rcMainSocket
|
||||||
clientList <- gets scClientSockets
|
|
||||||
clients <- liftIO $ STM.atomically $ STM.readTMVar clientList
|
|
||||||
serverState <- gets scServerState
|
serverState <- gets scServerState
|
||||||
|
clientList <- gets scClientSockets
|
||||||
void $ liftIO $ installHandler
|
void $ liftIO $ installHandler
|
||||||
sigINT
|
sigINT
|
||||||
(CatchOnce $ do
|
(CatchOnce $ do
|
||||||
putStrLn "SIGINT caught, terminating…"
|
putStrLn "SIGINT caught, terminating…"
|
||||||
|
clients <- liftIO $ STM.atomically $ STM.readTMVar clientList
|
||||||
disconnectClients clientList clients
|
disconnectClients clientList clients
|
||||||
close sock
|
close sock
|
||||||
st <- STM.atomically $ STM.readTMVar serverState
|
st <- STM.atomically $ STM.readTMVar serverState
|
||||||
|
@ -83,7 +83,9 @@ disconnectClients
|
||||||
:: STM.TMVar [ClientComms]
|
:: STM.TMVar [ClientComms]
|
||||||
-> [ClientComms]
|
-> [ClientComms]
|
||||||
-> IO ()
|
-> IO ()
|
||||||
disconnectClients clientList = mapM_
|
disconnectClients clientList clients = do
|
||||||
|
putStrLn "server shutting down. Notifying all clients…"
|
||||||
|
mapM_
|
||||||
(\client -> do
|
(\client -> do
|
||||||
maybe
|
maybe
|
||||||
(pure ())
|
(pure ())
|
||||||
|
@ -93,6 +95,7 @@ disconnectClients clientList = mapM_
|
||||||
)
|
)
|
||||||
(ccUUID client)
|
(ccUUID client)
|
||||||
)
|
)
|
||||||
|
clients
|
||||||
|
|
||||||
-- | Drops the client from internal management and closes its socket, if still present.
|
-- | Drops the client from internal management and closes its socket, if still present.
|
||||||
dropClient
|
dropClient
|
||||||
|
@ -126,8 +129,8 @@ processRequests = do
|
||||||
where
|
where
|
||||||
acceptConnection mainSocket socketList queue st = do
|
acceptConnection mainSocket socketList queue st = do
|
||||||
putStrLn "Ready for new connection requests…"
|
putStrLn "Ready for new connection requests…"
|
||||||
esock <- try $ accept mainSocket
|
eSock <- try $ accept mainSocket
|
||||||
case esock of
|
case eSock of
|
||||||
Left (_ :: SomeException) ->
|
Left (_ :: SomeException) ->
|
||||||
putStrLn "Main socket vanished!"
|
putStrLn "Main socket vanished!"
|
||||||
Right (clientSock, _) -> do
|
Right (clientSock, _) -> do
|
||||||
|
@ -135,7 +138,7 @@ processRequests = do
|
||||||
receiveMessage clientSock queue socketList
|
receiveMessage clientSock queue socketList
|
||||||
liftIO $ STM.atomically $ do
|
liftIO $ STM.atomically $ do
|
||||||
list <- STM.takeTMVar socketList
|
list <- STM.takeTMVar socketList
|
||||||
STM.putTMVar socketList ((ClientComms Nothing clientSock clientThreadId) : list)
|
STM.putTMVar socketList (ClientComms Nothing clientSock clientThreadId : list)
|
||||||
putStrLn "accepted new connection"
|
putStrLn "accepted new connection"
|
||||||
abortCondition <- serverStop <$> STM.atomically (STM.readTMVar st)
|
abortCondition <- serverStop <$> STM.atomically (STM.readTMVar st)
|
||||||
unless abortCondition $
|
unless abortCondition $
|
||||||
|
@ -150,7 +153,7 @@ sendMessage
|
||||||
-> IO ()
|
-> IO ()
|
||||||
sendMessage msg uuid clientList = do
|
sendMessage msg uuid clientList = do
|
||||||
clients <- STM.atomically $ STM.readTMVar clientList
|
clients <- STM.atomically $ STM.readTMVar clientList
|
||||||
let msock = ccSocket <$> find (\client -> ccUUID client == Just uuid) clients
|
let mSock = ccSocket <$> find (\client -> ccUUID client == Just uuid) clients
|
||||||
msgJson = A.encode msg
|
msgJson = A.encode msg
|
||||||
msgVector = VS.fromList $ B.unpack $ B.toStrict $ ('<' `B8.cons` (msgJson `B8.snoc` '>'))
|
msgVector = VS.fromList $ B.unpack $ B.toStrict $ ('<' `B8.cons` (msgJson `B8.snoc` '>'))
|
||||||
putStrLn $ "Sending: " <> B8.unpack msgJson
|
putStrLn $ "Sending: " <> B8.unpack msgJson
|
||||||
|
@ -159,9 +162,16 @@ sendMessage msg uuid clientList = do
|
||||||
(\sock ->
|
(\sock ->
|
||||||
VS.unsafeWith
|
VS.unsafeWith
|
||||||
msgVector
|
msgVector
|
||||||
(\ptr -> void $ sendBuf sock ptr (VS.length msgVector))
|
(\ptr -> do
|
||||||
|
eResult <- try $ void $ sendBuf sock ptr (VS.length msgVector)
|
||||||
|
case eResult of
|
||||||
|
Left (_ :: IOException) ->
|
||||||
|
putStrLn $ "cant reach client " <> show uuid
|
||||||
|
Right _ ->
|
||||||
|
pure ()
|
||||||
)
|
)
|
||||||
msock
|
)
|
||||||
|
mSock
|
||||||
|
|
||||||
-- | handle received messages
|
-- | handle received messages
|
||||||
handleMessages :: Game ()
|
handleMessages :: Game ()
|
||||||
|
@ -177,7 +187,6 @@ handleMessages = do
|
||||||
pure []
|
pure []
|
||||||
else
|
else
|
||||||
STM.flushTQueue queue
|
STM.flushTQueue queue
|
||||||
unless (null msgs) $ putStrLn "GET"
|
|
||||||
void $ do
|
void $ do
|
||||||
mapM_
|
mapM_
|
||||||
(handleMessage serverState readerContainer)
|
(handleMessage serverState readerContainer)
|
||||||
|
@ -191,11 +200,11 @@ receiveMessage
|
||||||
-> IO ()
|
-> IO ()
|
||||||
receiveMessage sock queue clientList = do
|
receiveMessage sock queue clientList = do
|
||||||
let maxBufferLength = 4096
|
let maxBufferLength = 4096
|
||||||
mmsg <- do
|
mMsg <- do
|
||||||
ptr <- mallocArray maxBufferLength
|
ptr <- mallocArray maxBufferLength
|
||||||
ebufferLength <-
|
eBufferLength <-
|
||||||
try $ recvBuf sock ptr maxBufferLength
|
try $ recvBuf sock ptr maxBufferLength
|
||||||
bufferLength <- case ebufferLength of
|
bufferLength <- case eBufferLength of
|
||||||
Left (_ :: IOException) -> do
|
Left (_ :: IOException) -> do
|
||||||
putStrLn "Socket vanished, cleaning up…"
|
putStrLn "Socket vanished, cleaning up…"
|
||||||
dropClient clientList sock
|
dropClient clientList sock
|
||||||
|
@ -212,11 +221,10 @@ receiveMessage sock queue clientList = do
|
||||||
maybe
|
maybe
|
||||||
(pure ())
|
(pure ())
|
||||||
(\msg -> do
|
(\msg -> do
|
||||||
putStrLn "PUT"
|
|
||||||
liftIO $ STM.atomically $ STM.writeTQueue queue msg
|
liftIO $ STM.atomically $ STM.writeTQueue queue msg
|
||||||
-- when (msg == IdRequest) (threadDelay $ 10 ^ 3)
|
-- when (msg == IdRequest) (threadDelay $ 10 ^ 3)
|
||||||
)
|
)
|
||||||
mmsg
|
mMsg
|
||||||
|
|
||||||
-- | function for translating 'ClientMessage's into server actions
|
-- | function for translating 'ClientMessage's into server actions
|
||||||
handleMessage
|
handleMessage
|
||||||
|
@ -232,10 +240,10 @@ handleMessage stateContainer readerContainer msg = do
|
||||||
IdRequest -> do
|
IdRequest -> do
|
||||||
clientId <- nextRandom
|
clientId <- nextRandom
|
||||||
let clientIdx = findIndex (isNothing . ccUUID) clients
|
let clientIdx = findIndex (isNothing . ccUUID) clients
|
||||||
let clientSock = ccSocket $ clients !! fromJust clientIdx
|
clientSock = ccSocket $ clients !! fromJust clientIdx
|
||||||
let newClients = map
|
newClients = map
|
||||||
(\old@(ClientComms muuid oldClientSock _) ->
|
(\old@(ClientComms mUUID oldClientSock _) ->
|
||||||
if oldClientSock == clientSock && isNothing muuid
|
if oldClientSock == clientSock && isNothing mUUID
|
||||||
then
|
then
|
||||||
old
|
old
|
||||||
{ ccUUID = Just clientId
|
{ ccUUID = Just clientId
|
||||||
|
@ -250,15 +258,9 @@ handleMessage stateContainer readerContainer msg = do
|
||||||
ClientMessage clientId payload ->
|
ClientMessage clientId payload ->
|
||||||
case payload of
|
case payload of
|
||||||
ClientQuit -> do
|
ClientQuit -> do
|
||||||
putStrLn $ "removing client " <> show clientId
|
putStrLn $ "client " <> show clientId <> " has quit the game"
|
||||||
let newClients = filter (\a -> ccUUID a /= Just clientId) clients
|
let client = find (\a -> ccUUID a == Just clientId) clients
|
||||||
client = find (\a -> ccUUID a == Just clientId) clients
|
dropClient clientList (ccSocket $ fromJust client)
|
||||||
STM.atomically $ do
|
|
||||||
currentPlayers <- STM.readTMVar (scPlayers stateContainer)
|
|
||||||
let newPlayers = filter (\p -> playerId p /= clientId) currentPlayers
|
|
||||||
void $ STM.swapTMVar (scPlayers stateContainer) newPlayers
|
|
||||||
void $ STM.swapTMVar clientList newClients
|
|
||||||
close (ccSocket $ fromJust client)
|
|
||||||
ClientRequestWizard -> do
|
ClientRequestWizard -> do
|
||||||
putStrLn "initializing new wizard"
|
putStrLn "initializing new wizard"
|
||||||
let arena = rcMap readerContainer
|
let arena = rcMap readerContainer
|
||||||
|
@ -273,28 +275,32 @@ handleMessage stateContainer readerContainer msg = do
|
||||||
sendMessage (ProvideInitialWizard freshWizard) clientId clientList
|
sendMessage (ProvideInitialWizard freshWizard) clientId clientList
|
||||||
ClientReady -> do
|
ClientReady -> do
|
||||||
putStrLn $ "client " <> show clientId <> " is ready!"
|
putStrLn $ "client " <> show clientId <> " is ready!"
|
||||||
|
now <- getCurrentTime
|
||||||
STM.atomically $ do
|
STM.atomically $ do
|
||||||
currentPlayers <- STM.readTMVar (scPlayers stateContainer)
|
currentPlayers <- STM.readTMVar (scPlayers stateContainer)
|
||||||
let (thisPlayers, otherPlayers) =
|
let (thisPlayers, otherPlayers) =
|
||||||
partition (\p -> playerId p == clientId) currentPlayers
|
partition (\p -> playerId p == clientId) currentPlayers
|
||||||
unless (null thisPlayers) $
|
unless (null thisPlayers) $
|
||||||
void $ STM.swapTMVar (scPlayers stateContainer) $
|
void $ STM.swapTMVar (scPlayers stateContainer) $
|
||||||
(head thisPlayers) {playerReady = True} : otherPlayers
|
(head thisPlayers)
|
||||||
|
{ playerReady = True
|
||||||
|
, playerLastPong = (now, snd (playerLastPong $ head thisPlayers))
|
||||||
|
}
|
||||||
|
: otherPlayers
|
||||||
Pong uuid -> do
|
Pong uuid -> do
|
||||||
let mclient = find (\c -> ccUUID c == Just clientId) clients
|
let mclient = find (\c -> ccUUID c == Just clientId) clients
|
||||||
maybe
|
maybe
|
||||||
(putStrLn $ "Who is " <> show uuid <> "?")
|
(putStrLn $ "Who is " <> show uuid <> "?")
|
||||||
(\client -> do
|
(\_ -> do
|
||||||
mplayer <- STM.atomically $ do
|
mPlayer <- STM.atomically $ do
|
||||||
players <- STM.readTMVar (scPlayers stateContainer)
|
players <- STM.readTMVar (scPlayers stateContainer)
|
||||||
pure $ find (\p -> playerId p == clientId) players
|
pure $ find (\p -> playerId p == clientId) players
|
||||||
maybe
|
maybe
|
||||||
(pure ())
|
(pure ())
|
||||||
(\player ->
|
(\player ->
|
||||||
if snd (playerLastPong player) /= uuid
|
if snd (playerLastPong player) /= uuid
|
||||||
then do
|
then
|
||||||
putStrLn $ "dropping client " <> show clientId
|
putStrLn $ "Pong ID mismatch from " <> show clientId
|
||||||
dropClient clientList (ccSocket client)
|
|
||||||
else do
|
else do
|
||||||
now <- getCurrentTime
|
now <- getCurrentTime
|
||||||
STM.atomically$ do
|
STM.atomically$ do
|
||||||
|
@ -305,7 +311,7 @@ handleMessage stateContainer readerContainer msg = do
|
||||||
}
|
}
|
||||||
void $ STM.swapTMVar (scPlayers stateContainer) (modPlayer : otherPlayers)
|
void $ STM.swapTMVar (scPlayers stateContainer) (modPlayer : otherPlayers)
|
||||||
)
|
)
|
||||||
mplayer
|
mPlayer
|
||||||
)
|
)
|
||||||
mclient
|
mclient
|
||||||
|
|
||||||
|
@ -330,7 +336,7 @@ sendPings = do
|
||||||
put stateContainer
|
put stateContainer
|
||||||
else do
|
else do
|
||||||
random <- liftIO nextRandom
|
random <- liftIO nextRandom
|
||||||
let newPong = (now, random)
|
let newPong = (lastPongTime, random)
|
||||||
liftIO $ sendMessage
|
liftIO $ sendMessage
|
||||||
( Ping random
|
( Ping random
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue