netserver/hwserv.hs
changeset 849 82ac0596aa3c
child 851 8ffa4ad0d8ea
equal deleted inserted replaced
848:b31b72756927 849:82ac0596aa3c
       
     1 module Main where
       
     2 
       
     3 import Network
       
     4 import IO
       
     5 import System.IO
       
     6 import Control.Concurrent
       
     7 import Control.Concurrent.STM
       
     8 import Control.Exception (finally)
       
     9 import Miscutils
       
    10 
       
    11 data ClientInfo =
       
    12 	ClientInfo
       
    13 	{
       
    14 		handle :: Handle,
       
    15 		nick :: String,
       
    16 		game :: String,
       
    17 		isMaster :: Bool
       
    18 	}
       
    19 
       
    20 data RoomInfo =
       
    21 	RoomInfo
       
    22 	{
       
    23 		name :: String,
       
    24 		password :: String
       
    25 	}
       
    26 
       
    27 
       
    28 handleCmd :: Handle -> TVar[ClientInfo] -> TVar[RoomInfo] -> (String, [String]) -> IO()
       
    29 handleCmd clientHandle clientsList roomsList ("SAY", param) = do
       
    30 		ls <- atomically(readTVar clientsList)
       
    31 		sendOthers (map (\x -> handle x) ls) clientHandle (concat param)
       
    32 		return ()
       
    33 
       
    34 handleCmd clientHandle clientsList roomsList ("CREATE", [roomname]) = do
       
    35 		manipState roomsList (\x -> (RoomInfo roomname ""):x)
       
    36 		manipState clientsList (\x -> map (\xc -> if (clientHandle == handle xc) then xc{isMaster = True, game = roomname} else xc) x)
       
    37 		sendMsg clientHandle ("JOINED " ++ roomname)
       
    38 
       
    39 handleCmd clientHandle clientsList roomsList ("LIST", []) = do
       
    40 		rl <- atomically $ readTVar roomsList
       
    41 		sendMsg clientHandle (unlines $ map (\x -> name x) rl)
       
    42 
       
    43 handleCmd clientHandle _ _ ("PING", _) = sendMsg clientHandle "PONG"
       
    44 
       
    45 handleCmd clientHandle _ _ (_, _) = sendMsg clientHandle "Unknown cmd or bad syntax"
       
    46 
       
    47 
       
    48 clientLoop :: Handle -> TVar[ClientInfo] -> TVar[RoomInfo] -> IO()
       
    49 clientLoop clientHandle clientsList roomsList = do
       
    50 		cline <- hGetLine clientHandle
       
    51 		let (cmd, params) = extractCmd cline
       
    52 		handleCmd clientHandle clientsList roomsList (cmd, params)
       
    53 		if cmd /= "QUIT" then clientLoop clientHandle clientsList roomsList else return ()
       
    54 
       
    55 
       
    56 main = do
       
    57 	clientsList <- atomically $ newTVar[]
       
    58 	roomsList <- atomically $ newTVar[]
       
    59 	bracket
       
    60 		(listenOn $ PortNumber 46631)
       
    61 		(sClose)
       
    62 		(loop clientsList roomsList)
       
    63 		where
       
    64 			loop clist rlist sock = accept sock >>= addClient clist rlist >> loop clist rlist sock
       
    65 
       
    66 			addClient clist rlist (chandle, hostname, port) = do
       
    67 				putStrLn $ "Client connected: " ++ show hostname
       
    68 				hSetBuffering chandle LineBuffering
       
    69 				manipState clist (\x -> (ClientInfo chandle "" "" False):x) -- add client to list
       
    70 				forkIO $ finally
       
    71 					(clientLoop chandle clist rlist)
       
    72 					(do
       
    73 					manipState clist (\x -> filter (\x -> chandle /= handle x) x) -- remove client from list
       
    74 					hClose chandle)