begin synchronisation primitives

This commit is contained in:
nek0 2024-02-02 08:16:28 +01:00
parent 14fd41ef04
commit 6587f97312
2 changed files with 43 additions and 53 deletions

View file

@ -26,6 +26,8 @@ import Data.Maybe
import Data.UUID hiding (null) import Data.UUID hiding (null)
import Data.UUID.V4 import Data.UUID.V4
import Data.Time
import qualified Data.Vector.Storable as VS import qualified Data.Vector.Storable as VS
import Foreign hiding (void) import Foreign hiding (void)
@ -78,12 +80,15 @@ terminateGameOnSigint path = do
-- raiseSignal sigINT -- raiseSignal sigINT
) )
Nothing Nothing
where
disconnectClients = mapM_ disconnectClients
(\(_, clientSocket) -> do :: [Client]
sendMessage ServerQuit clientSocket -> IO ()
close clientSocket disconnectClients = mapM_
) (\(_, clientSocket) -> do
sendMessage ServerQuit clientSocket
close clientSocket
)
-- | Process incoming connection requests -- | Process incoming connection requests
processRequests :: Game () processRequests :: Game ()
@ -178,11 +183,11 @@ handleMessage stateContainer readerContainer msg = do
case msg of case msg of
IdRequest -> do IdRequest -> do
clientId <- nextRandom clientId <- nextRandom
let clientIdx = findIndex (\a -> fst a == Nothing) clients let clientIdx = findIndex (isNothing . fst) clients
let clientSock = snd $ clients !! fromJust clientIdx let clientSock = snd $ clients !! fromJust clientIdx
let newClients = map let newClients = map
(\old@(muuid, oldClientSock) -> (\old@(muuid, oldClientSock) ->
if oldClientSock == clientSock && muuid == Nothing if oldClientSock == clientSock && isNothing muuid
then then
(Just clientId, clientSock) (Just clientId, clientSock)
else else
@ -224,49 +229,29 @@ handleMessage stateContainer readerContainer msg = do
(head thisPlayers) {playerReady = True} : otherPlayers (head thisPlayers) {playerReady = True} : otherPlayers
_ -> pure () _ -> pure ()
sendUpdates :: Game () sendPings :: Game ()
sendUpdates = do sendPings = do
now <- liftIO getCurrentTime
tileMap <- asks rcMap tileMap <- asks rcMap
maxTimeout <- asks rcClientMaxTimeout
framesPerPing <- asks rcFramesPerPing
fps <- asks rcFPS
stateContainer <- get stateContainer <- get
players <- liftIO $ STM.atomically $ STM.readTMVar (scPlayers stateContainer) players <- liftIO $ STM.atomically $ STM.readTMVar (scPlayers stateContainer)
sockets <- liftIO $ STM.atomically $ STM.readTMVar (scClientSockets stateContainer) sockets <- liftIO $ STM.atomically $ STM.readTMVar (scClientSockets stateContainer)
mapM_ mapM_
(\(Player playerId wizard@(Wizard {..}) readiness) -> do (\(Player playerId (Wizard {}) readiness lastPong) -> do
when readiness $ do let timeDiff = realToFrac $ diffUTCTime now lastPong
let V2 wr wc = wizardPos when (readiness && timeDiff > (framesPerPing * recip fps)) $ do
subCoords = (,) <$> [floor wr - 4 .. floor wr + 4] <*> [floor wc - 4 .. floor wc + 4] let clientSock = fromJust (lookup (Just playerId) sockets)
leftBound = wizardRot + (pi / 4) if timeDiff > maxTimeout
rightBound = wizardRot - (pi / 4) then
leftLine row = cos leftBound * row liftIO $ disconnectClients [clientSock]
rightLine row = sin rightBound * row else do
correctionLeft = if wizardRot < pi / 2 || wizardRot > 4 * pi / 2 random <- liftIO $ nextRandom
then floor liftIO $ sendMessage
else ceiling ( Ping random
correctionRight = if wizardRot < pi / 2 || wizardRot > 4 * pi / 2 )
then ceiling clientSock
else floor
viewMatrix = M.fromList 9 9 $ map
(\(qr, qc) ->
if qc - floor wc <= correctionLeft (leftLine (wr - fromIntegral qr))
&& qc - floor wc >= correctionRight (rightLine (wr - fromIntegral qr))
then
M.safeGet qr qc tileMap
else
Nothing
)
subCoords
clientSock = fromJust $ lookup (Just playerId) sockets
-- liftIO $ print $ leftLine . (\x -> x - wr) . fromIntegral .fst <$> subCoords
-- liftIO $ print initViewMatrix
liftIO $ sendMessage
(TickUpdate
{ tuWizard = wizard
, tuMapSlice = MapSlice
{ msViewMap = viewMatrix
, msContents = []
}
}
)
clientSock
) )
players players

View file

@ -27,6 +27,8 @@ data Settings = Settings
, setMapColumns :: Int , setMapColumns :: Int
, setSpawnerProbability :: Float , setSpawnerProbability :: Float
, setFPS :: Int , setFPS :: Int
, setClientMaxTimeout :: Float
, setFramesPerPing :: Int
} }
deriving (Show, Generic) deriving (Show, Generic)
@ -46,9 +48,11 @@ options = Options
) )
data ReaderContainer = ReaderContainer data ReaderContainer = ReaderContainer
{ rcMap :: ServerMap { rcMap :: ServerMap
, rcFPS :: Int , rcFPS :: Int
, rcMainSocket :: Socket , rcFramesPerPing :: Int
, rcClientMaxTimeout :: Float
, rcMainSocket :: Socket
} }
deriving (Eq, Show) deriving (Eq, Show)
@ -62,9 +66,10 @@ data StateContainer = StateContainer
} }
data Player = Player data Player = Player
{ playerId :: UUID { playerId :: UUID
, playerWizard :: Wizard , playerWizard :: Wizard
, playerReady :: Bool , playerReady :: Bool
, playerLastPong :: UTCTime
} }
deriving (Eq, Show) deriving (Eq, Show)