first working socket experiments

This commit is contained in:
nek0 2023-12-10 02:02:09 +01:00
parent 734511b5f9
commit 822a2178b4
5 changed files with 56 additions and 16 deletions

View file

@ -31,13 +31,6 @@ data ClientState = ClientState
, clientStop :: Bool -- ^ client shutdown , clientStop :: Bool -- ^ client shutdown
} }
-- | Data object for storing the server's state
data ServerState = ServerState
{ serverGameOver :: Bool -- ^ global game over state (only one contestant left)
, serverStop :: Bool -- ^ Server shutdown
}
deriving (Show, Eq)
-- | Type synonym for the Map. Translates to a Matrix of 'Tile's -- | Type synonym for the Map. Translates to a Matrix of 'Tile's
type ServerMap = Matrix Tile type ServerMap = Matrix Tile

View file

@ -40,7 +40,7 @@ main = do
Right (Settings {..}) -> do Right (Settings {..}) -> do
sock <- bindSocket setSocketPath sock <- bindSocket setSocketPath
terminateSocketOnSigint sock terminateSocketOnSigint sock
Net.listen sock 1024 -- Net.listen sock 1024
putStrLn "Bound and listening to socket:" putStrLn "Bound and listening to socket:"
print =<< getSocketName sock print =<< getSocketName sock
putStrLn "-----------------------------------------------------------------------------------" putStrLn "-----------------------------------------------------------------------------------"
@ -51,7 +51,7 @@ main = do
putStrLn "starting game…" putStrLn "starting game…"
now <- getCurrentTime now <- getCurrentTime
let initRead = ReaderContainer (arenaMap arena) setFPS sock let initRead = ReaderContainer (arenaMap arena) setFPS sock
initState = StateContainer (arenaSpawners arena) [] (ServerState False False) now initState = StateContainer (arenaSpawners arena) [] (ServerState False False) now []
(finalState, finalWrite) <- execRWST runGame initRead initState (finalState, finalWrite) <- execRWST runGame initRead initState
print finalWrite print finalWrite
where where

View file

@ -1,13 +1,21 @@
{-# LANGUAGE OverloadedStrings #-}
module Server.Communication where module Server.Communication where
import Control.Monad import Control.Monad
import Network.Socket import Control.Monad.IO.Class
import Control.Monad.RWS.Strict
import Network.Socket as Net
import System.IO
import System.Posix.Signals import System.Posix.Signals
-- internal imports -- internal imports
import Server.Types
import Server.Util import Server.Util
-- | Function which determines whether the given filePath is a supported socket path and -- | Function which determines whether the given filePath is a supported socket path and
@ -20,8 +28,9 @@ bindSocket path = do
unless (isSupportedSockAddr sockAddr) unless (isSupportedSockAddr sockAddr)
(error $ "invalid socket path " <> path) (error $ "invalid socket path " <> path)
-- aremoveIfExists path -- aremoveIfExists path
sock <- socket AF_UNIX Stream 0 sock <- socket AF_UNIX Stream defaultProtocol
bind sock sockAddr bind sock sockAddr
Net.listen sock 5
pure sock pure sock
-- | Function that installs a handler on SIGINT to close and remove the given socket -- | Function that installs a handler on SIGINT to close and remove the given socket
@ -39,3 +48,29 @@ terminateSocketOnSigint sock =
raiseSignal keyboardSignal raiseSignal keyboardSignal
) )
Nothing Nothing
-- | Process incoming connection requests
processRequests :: Game
processRequests = do
mainSocket <- asks rcMainSocket
clientSock <- liftIO $ do
(clientSock, _) <- accept mainSocket
putStrLn $ "accepted new connection"
pure clientSock
modify' (\st ->
st
{scClientSockets = clientSock : scClientSockets st}
)
-- | process incomeing messages from clients
processMessages :: Game
processMessages = do
clientSocks <- gets scClientSockets
mapM_
(\clientSocket -> liftIO $ do
connectionHandle <- socketToHandle clientSocket ReadMode
hSetBuffering connectionHandle LineBuffering
messages <- hGetContents' connectionHandle
print messages
)
clientSocks

View file

@ -12,6 +12,7 @@ import Data.Time
import Library.Types import Library.Types
import Server.Communication
import Server.Types import Server.Types
runGame :: Game runGame :: Game
@ -22,6 +23,9 @@ runGame = do
before <- gets scServerLastTick before <- gets scServerLastTick
now <- liftIO getCurrentTime now <- liftIO getCurrentTime
let delta = realToFrac $ diffUTCTime now before let delta = realToFrac $ diffUTCTime now before
processRequests
processMessages
updateSpawners delta updateSpawners delta
updateWizards delta updateWizards delta
fps <- asks rcFPS fps <- asks rcFPS
@ -32,7 +36,7 @@ runGame = do
updateSpawners :: Float -> Game updateSpawners :: Float -> Game
updateSpawners dt = updateSpawners dt =
modify' (\sc@(StateContainer spawners _ _ _) -> modify' (\sc@(StateContainer spawners _ _ _ _) ->
let newSpawners = map let newSpawners = map
(\spawner -> do (\spawner -> do
let newTTL = spawnerReloadTTL spawner - dt let newTTL = spawnerReloadTTL spawner - dt
@ -53,7 +57,7 @@ updateSpawners dt =
updateWizards :: Float -> Game updateWizards :: Float -> Game
updateWizards dt = updateWizards dt =
modify' (\sc@(StateContainer _ wizards _ _) -> modify' (\sc@(StateContainer _ wizards _ _ _) ->
let newWizards = map let newWizards = map
(\wizard@(Wizard _ _ health _ _ effects) -> (\wizard@(Wizard _ _ health _ _ effects) ->
let newEffects = foldl let newEffects = foldl

View file

@ -42,7 +42,7 @@ options = Options
data ReaderContainer = ReaderContainer data ReaderContainer = ReaderContainer
{ rcMap :: ServerMap { rcMap :: ServerMap
, rcFPS :: Int , rcFPS :: Int
, rcSocket :: Socket , rcMainSocket :: Socket
} }
deriving (Eq, Show) deriving (Eq, Show)
@ -51,6 +51,14 @@ data StateContainer = StateContainer
, scPlayers :: [ Wizard ] , scPlayers :: [ Wizard ]
, scServerState :: ServerState , scServerState :: ServerState
, scServerLastTick :: UTCTime , scServerLastTick :: UTCTime
, scClientSockets :: [ Socket ]
} }
-- | Data object for storing the server's state
data ServerState = ServerState
{ serverGameOver :: Bool -- ^ global game over state (only one contestant left)
, serverStop :: Bool -- ^ Server shutdown
}
deriving (Show, Eq)
type Game = RWST ReaderContainer String StateContainer IO () type Game = RWST ReaderContainer String StateContainer IO ()