2018-04-11 13:25:24 +02:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
|
|
|
module Main where
|
|
|
|
|
2019-10-13 22:00:35 +02:00
|
|
|
import qualified App (Context(..), T, update_)
|
|
|
|
import qualified Automaton (start)
|
|
|
|
import qualified Config (listenPort)
|
2018-04-18 15:27:59 +02:00
|
|
|
import Control.Concurrent (newMVar, modifyMVar)
|
|
|
|
import Control.Exception (finally)
|
2019-10-13 22:00:35 +02:00
|
|
|
import Control.Monad.Reader (ReaderT(..), asks)
|
2019-08-24 23:29:40 +02:00
|
|
|
import qualified Hanafuda.Message as Message (FromClient(..))
|
|
|
|
import Messaging (broadcast, relay)
|
2019-10-13 22:00:35 +02:00
|
|
|
import Network.HTTP.Types.Status (badRequest400)
|
|
|
|
import Network.Wai (responseLBS)
|
|
|
|
import Network.Wai.Handler.Warp (run)
|
|
|
|
import Network.Wai.Handler.WebSockets (websocketsOr)
|
|
|
|
import Network.WebSockets (ServerApp, acceptRequest, defaultConnectionOptions)
|
|
|
|
import qualified Server (disconnect, new, register)
|
|
|
|
import qualified Session (open)
|
2018-04-11 13:25:24 +02:00
|
|
|
|
2018-05-11 12:31:53 +02:00
|
|
|
exit :: App.T ()
|
2018-04-11 13:25:24 +02:00
|
|
|
exit = do
|
2019-08-24 23:29:40 +02:00
|
|
|
asks App.playerID >>= App.update_ . Server.disconnect
|
|
|
|
relay Message.LogOut broadcast
|
2018-04-11 13:25:24 +02:00
|
|
|
|
2018-05-11 12:31:53 +02:00
|
|
|
serverApp :: App.T () -> App.T () -> IO ServerApp
|
2018-04-18 15:27:59 +02:00
|
|
|
serverApp onEnter onExit = do
|
|
|
|
mServer <- newMVar Server.new
|
|
|
|
return $ \pending -> do
|
2018-05-11 12:31:53 +02:00
|
|
|
session <- Session.open <$> acceptRequest pending
|
2019-08-24 23:29:40 +02:00
|
|
|
playerID <- modifyMVar mServer (return . Server.register session)
|
|
|
|
let app = App.Context {App.mServer, App.playerID}
|
2018-04-18 15:27:59 +02:00
|
|
|
finally
|
2018-05-11 12:31:53 +02:00
|
|
|
(runReaderT onEnter app)
|
|
|
|
(runReaderT onExit app)
|
2018-04-18 15:27:59 +02:00
|
|
|
|
2018-04-11 13:25:24 +02:00
|
|
|
main :: IO ()
|
|
|
|
main = do
|
2018-04-18 15:27:59 +02:00
|
|
|
app <- serverApp Automaton.start exit
|
2018-04-11 13:25:24 +02:00
|
|
|
run Config.listenPort $ websocketsOr defaultConnectionOptions app blockNonWS
|
|
|
|
where
|
|
|
|
blockNonWS _ = ( $ responseLBS badRequest400 [] "Use a websocket")
|