GameServer: Use consistent formatting of clan chat (compared with engine)
It's called "clan chat" now, not "team chat". Also the brackets and text positions
were inconsistent with engine.
{- * Hedgewars, a free turn based strategy game * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. \-}{-# LANGUAGE BangPatterns, GeneralizedNewtypeDeriving #-}module RoomsAndClients( RoomIndex(), ClientIndex(), MRoomsAndClients(), IRoomsAndClients(), newRoomsAndClients, addRoom, addClient, removeRoom, removeClient, modifyRoom, modifyClient, lobbyId, moveClientToLobby, moveClientToRoom, clientRoomM, clientExists, client, room, client'sM, room'sM, allClientsM, allRoomsM, clientsM, roomsM, roomClientsM, roomClientsIndicesM, withRoomsAndClients, allRooms, allClients, clientRoom, showRooms, roomClients ) whereimport Storeimport Control.Monadimport Control.DeepSeqdata Room r = Room { roomClients' :: ![ClientIndex], room' :: !r }data Client c = Client { clientRoom' :: !RoomIndex, client' :: !c }newtype RoomIndex = RoomIndex ElemIndex deriving (Eq, NFData)newtype ClientIndex = ClientIndex ElemIndex deriving (Eq, Show, Read, Ord, NFData)instance Show RoomIndex where show (RoomIndex i) = 'r' : show iunRoomIndex :: RoomIndex -> ElemIndexunRoomIndex (RoomIndex r) = runClientIndex :: ClientIndex -> ElemIndexunClientIndex (ClientIndex c) = cnewtype MRoomsAndClients r c = MRoomsAndClients (MStore (Room r), MStore (Client c))newtype IRoomsAndClients r c = IRoomsAndClients (IStore (Room r), IStore (Client c))lobbyId :: RoomIndexlobbyId = RoomIndex firstIndexnewRoomsAndClients :: r -> IO (MRoomsAndClients r c)newRoomsAndClients r = do rooms <- newStore clients <- newStore let rnc = MRoomsAndClients (rooms, clients) ri <- addRoom rnc r when (ri /= lobbyId) $ error "Empty struct inserts not at firstIndex index" return rncroomAddClient :: ClientIndex -> Room r -> Room rroomAddClient cl rm = let cls = cl : roomClients' rm; nr = rm{roomClients' = cls} in cls `deepseq` nrroomRemoveClient :: ClientIndex -> Room r -> Room rroomRemoveClient cl rm = let cls = filter (/= cl) $ roomClients' rm; nr = rm{roomClients' = cls} in cls `deepseq` nraddRoom :: MRoomsAndClients r c -> r -> IO RoomIndexaddRoom (MRoomsAndClients (rooms, _)) rm = do i <- addElem rooms (Room [] rm) return $ RoomIndex iaddClient :: MRoomsAndClients r c -> c -> IO ClientIndexaddClient (MRoomsAndClients (rooms, clients)) cl = do i <- addElem clients (Client lobbyId cl) modifyElem rooms (roomAddClient (ClientIndex i)) (unRoomIndex lobbyId) return $ ClientIndex iremoveRoom :: MRoomsAndClients r c -> RoomIndex -> IO ()removeRoom rnc@(MRoomsAndClients (rooms, _)) rm@(RoomIndex ri) | rm == lobbyId = error "Cannot delete lobby" | otherwise = do clIds <- liftM roomClients' $ readElem rooms ri forM_ clIds (moveClientToLobby rnc) removeElem rooms riremoveClient :: MRoomsAndClients r c -> ClientIndex -> IO ()removeClient (MRoomsAndClients (rooms, clients)) cl@(ClientIndex ci) = do RoomIndex ri <- liftM clientRoom' $ readElem clients ci modifyElem rooms (roomRemoveClient cl) ri removeElem clients cimodifyRoom :: MRoomsAndClients r c -> (r -> r) -> RoomIndex -> IO ()modifyRoom (MRoomsAndClients (rooms, _)) f (RoomIndex ri) = modifyElem rooms (\r -> r{room' = f $ room' r}) rimodifyClient :: MRoomsAndClients r c -> (c -> c) -> ClientIndex -> IO ()modifyClient (MRoomsAndClients (_, clients)) f (ClientIndex ci) = modifyElem clients (\c -> c{client' = f $ client' c}) cimoveClientInRooms :: MRoomsAndClients r c -> RoomIndex -> RoomIndex -> ClientIndex -> IO ()moveClientInRooms (MRoomsAndClients (rooms, clients)) (RoomIndex riFrom) rt@(RoomIndex riTo) cl@(ClientIndex ci) = do modifyElem rooms (roomRemoveClient cl) riFrom modifyElem rooms (roomAddClient cl) riTo modifyElem clients (\c -> c{clientRoom' = rt}) cimoveClientToLobby :: MRoomsAndClients r c -> ClientIndex -> IO ()moveClientToLobby rnc ci = do rm <- clientRoomM rnc ci moveClientInRooms rnc rm lobbyId cimoveClientToRoom :: MRoomsAndClients r c -> RoomIndex -> ClientIndex -> IO ()moveClientToRoom rnc = moveClientInRooms rnc lobbyIdclientExists :: MRoomsAndClients r c -> ClientIndex -> IO BoolclientExists (MRoomsAndClients (_, clients)) (ClientIndex ci) = elemExists clients ciclientRoomM :: MRoomsAndClients r c -> ClientIndex -> IO RoomIndexclientRoomM (MRoomsAndClients (_, clients)) (ClientIndex ci) = liftM clientRoom' (clients `readElem` ci)client'sM :: MRoomsAndClients r c -> (c -> a) -> ClientIndex -> IO aclient'sM (MRoomsAndClients (_, clients)) f (ClientIndex ci) = liftM (f . client') (clients `readElem` ci)room'sM :: MRoomsAndClients r c -> (r -> a) -> RoomIndex -> IO aroom'sM (MRoomsAndClients (rooms, _)) f (RoomIndex ri) = liftM (f . room') (rooms `readElem` ri)allClientsM :: MRoomsAndClients r c -> IO [ClientIndex]allClientsM (MRoomsAndClients (_, clients)) = liftM (map ClientIndex) $ indicesM clientsallRoomsM :: MRoomsAndClients r c -> IO [RoomIndex]allRoomsM (MRoomsAndClients (rooms, _)) = liftM (map RoomIndex) $ indicesM roomsclientsM :: MRoomsAndClients r c -> IO [c]clientsM (MRoomsAndClients (_, clients)) = indicesM clients >>= mapM (liftM client' . readElem clients)roomsM :: MRoomsAndClients r c -> IO [r]roomsM (MRoomsAndClients (rooms, _)) = indicesM rooms >>= mapM (liftM room' . readElem rooms)roomClientsIndicesM :: MRoomsAndClients r c -> RoomIndex -> IO [ClientIndex]roomClientsIndicesM (MRoomsAndClients (rooms, _)) (RoomIndex ri) = liftM roomClients' (rooms `readElem` ri)roomClientsM :: MRoomsAndClients r c -> RoomIndex -> IO [c]roomClientsM (MRoomsAndClients (rooms, clients)) (RoomIndex ri) = liftM roomClients' (rooms `readElem` ri) >>= mapM (\(ClientIndex ci) -> liftM client' $ readElem clients ci)withRoomsAndClients :: MRoomsAndClients r c -> (IRoomsAndClients r c -> a) -> IO awithRoomsAndClients (MRoomsAndClients (rooms, clients)) f = withIStore2 rooms clients (\r c -> f $ IRoomsAndClients (r, c))--------------------------------------------------- IRoomsAndClients -----------showRooms :: (Show r, Show c) => IRoomsAndClients r c -> StringshowRooms rnc@(IRoomsAndClients (rooms, clients)) = concatMap showRoom (allRooms rnc) where showRoom r = unlines $ (show r ++ ": " ++ (show . room' $ rooms ! unRoomIndex r)) : map showClient (roomClients' $ rooms ! unRoomIndex r) showClient c = " " ++ show c ++ ": " ++ (show . client' $ clients ! unClientIndex c)allRooms :: IRoomsAndClients r c -> [RoomIndex]allRooms (IRoomsAndClients (rooms, _)) = map RoomIndex $ indices roomsallClients :: IRoomsAndClients r c -> [ClientIndex]allClients (IRoomsAndClients (_, clients)) = map ClientIndex $ indices clientsclientRoom :: IRoomsAndClients r c -> ClientIndex -> RoomIndexclientRoom (IRoomsAndClients (_, clients)) (ClientIndex ci) = clientRoom' (clients ! ci)client :: IRoomsAndClients r c -> ClientIndex -> cclient (IRoomsAndClients (_, clients)) (ClientIndex ci) = client' (clients ! ci)room :: IRoomsAndClients r c -> RoomIndex -> rroom (IRoomsAndClients (rooms, _)) (RoomIndex ri) = room' (rooms ! ri)roomClients :: IRoomsAndClients r c -> RoomIndex -> [ClientIndex]roomClients (IRoomsAndClients (rooms, _)) (RoomIndex ri) = roomClients' (rooms ! ri)