diff -r 54e4b03e6ba6 -r 87e5a6c3882c netserver/hedgewars-server.hs --- a/netserver/hedgewars-server.hs Sun Nov 02 11:46:58 2008 +0000 +++ b/netserver/hedgewars-server.hs Sun Nov 02 20:41:02 2008 +0000 @@ -6,7 +6,7 @@ import Control.Concurrent import Control.Concurrent.STM import Control.Exception (setUncaughtExceptionHandler, handle, finally) -import Control.Monad (forM, forM_, filterM, liftM, when, unless) +import Control.Monad import Maybe (fromMaybe, isJust, fromJust) import Data.List import Miscutils @@ -17,6 +17,15 @@ import System.Posix #endif +data Messages = + Accept ClientInfo + | ClientMessage ([String], ClientInfo) + | CoreMessage [String] + +messagesLoop :: TChan [String] -> IO() +messagesLoop messagesChan = forever $ do + threadDelay (30 * 10^6) -- 30 seconds + atomically $ writeTChan messagesChan ["PING"] acceptLoop :: Socket -> TChan ClientInfo -> IO () acceptLoop servSock acceptChan = do @@ -80,24 +89,35 @@ if isJust quitClient then reactCmd ["QUIT"] (fromJust quitClient) clientsIn mrooms else return (clientsIn, mrooms) -mainLoop :: Socket -> TChan ClientInfo -> [ClientInfo] -> [RoomInfo] -> IO () -mainLoop servSock acceptChan clients rooms = do - r <- atomically $ (Left `fmap` readTChan acceptChan) `orElse` (Right `fmap` tselect clients) +mainLoop :: Socket -> TChan ClientInfo -> TChan [String] -> [ClientInfo] -> [RoomInfo] -> IO () +mainLoop servSock acceptChan messagesChan clients rooms = do + r <- atomically $ (Accept `fmap` readTChan acceptChan) `orElse` (ClientMessage `fmap` tselect clients) `orElse` (CoreMessage `fmap` readTChan messagesChan) case r of - Left ci -> do - mainLoop servSock acceptChan (clients ++ [ci]) rooms - Right (cmd, client) -> do + Accept ci -> + mainLoop servSock acceptChan messagesChan (clients ++ [ci]) rooms + ClientMessage (cmd, client) -> do (clientsIn, mrooms) <- reactCmd cmd client clients rooms let hadRooms = (not $ null rooms) && (null mrooms) in unless ((not $ isDedicated globalOptions) && ((null clientsIn) || hadRooms)) $ - mainLoop servSock acceptChan clientsIn mrooms + mainLoop servSock acceptChan messagesChan clientsIn mrooms + CoreMessage msg -> if not $ null $ clients then + do + let client = head clients -- don't care + (clientsIn, mrooms) <- reactCmd msg client clients rooms + mainLoop servSock acceptChan messagesChan clientsIn mrooms + else + mainLoop servSock acceptChan messagesChan clients rooms startServer serverSocket = do acceptChan <- atomically newTChan forkIO $ acceptLoop serverSocket acceptChan - mainLoop serverSocket acceptChan [] [] + + messagesChan <- atomically newTChan + forkIO $ messagesLoop messagesChan + + mainLoop serverSocket acceptChan messagesChan [] [] main = withSocketsDo $ do