netserver/hedgewars-server.hs
changeset 1461 87e5a6c3882c
parent 1403 b8c921ed0f13
child 1463 659157f76171
--- 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