185 processAction (MoveToLobby msg) = do |
186 processAction (MoveToLobby msg) = do |
186 (Just ci) <- gets clientIndex |
187 (Just ci) <- gets clientIndex |
187 ri <- clientRoomA |
188 ri <- clientRoomA |
188 rnc <- gets roomsClients |
189 rnc <- gets roomsClients |
189 playersNum <- io $ room'sM rnc playersIn ri |
190 playersNum <- io $ room'sM rnc playersIn ri |
|
191 specialRoom <- io $ room'sM rnc isSpecial ri |
190 master <- client's isMaster |
192 master <- client's isMaster |
191 -- client <- client's id |
193 -- client <- client's id |
192 clNick <- client's nick |
194 clNick <- client's nick |
193 chans <- othersChans |
195 chans <- othersChans |
194 |
196 |
195 if master then |
197 if master then |
196 if playersNum > 1 then |
198 if (playersNum > 1) || specialRoom then |
197 mapM_ processAction [ChangeMaster Nothing, NoticeMessage AdminLeft, RemoveClientTeams, AnswerClients chans ["LEFT", clNick, msg]] |
199 mapM_ processAction [ChangeMaster Nothing, NoticeMessage AdminLeft, RemoveClientTeams, AnswerClients chans ["LEFT", clNick, msg]] |
198 else |
200 else |
199 processAction RemoveRoom |
201 processAction RemoveRoom |
200 else |
202 else |
201 mapM_ processAction [RemoveClientTeams, AnswerClients chans ["LEFT", clNick, msg]] |
203 mapM_ processAction [RemoveClientTeams, AnswerClients chans ["LEFT", clNick, msg]] |
203 allClientsChans <- liftM (Prelude.map sendChan . Prelude.filter isVisible) $! allClientsS |
205 allClientsChans <- liftM (Prelude.map sendChan . Prelude.filter isVisible) $! allClientsS |
204 processAction $ AnswerClients allClientsChans ["CLIENT_FLAGS", "-i", clNick] |
206 processAction $ AnswerClients allClientsChans ["CLIENT_FLAGS", "-i", clNick] |
205 |
207 |
206 -- when not removing room |
208 -- when not removing room |
207 ready <- client's isReady |
209 ready <- client's isReady |
208 when (not master || playersNum > 1) . io $ do |
210 when (not master || playersNum > 1 || specialRoom) . io $ do |
209 modifyRoom rnc (\r -> r{ |
211 modifyRoom rnc (\r -> r{ |
210 playersIn = playersIn r - 1, |
212 playersIn = playersIn r - 1, |
211 readyPlayers = if ready then readyPlayers r - 1 else readyPlayers r |
213 readyPlayers = if ready then readyPlayers r - 1 else readyPlayers r |
212 }) ri |
214 }) ri |
213 moveClientToLobby rnc ci |
215 moveClientToLobby rnc ci |
216 processAction (ChangeMaster delegateId)= do |
218 processAction (ChangeMaster delegateId)= do |
217 (Just ci) <- gets clientIndex |
219 (Just ci) <- gets clientIndex |
218 proto <- client's clientProto |
220 proto <- client's clientProto |
219 ri <- clientRoomA |
221 ri <- clientRoomA |
220 rnc <- gets roomsClients |
222 rnc <- gets roomsClients |
221 newMasterId <- liftM (\ids -> fromMaybe (last . filter (/= ci) $ ids) delegateId) . io $ roomClientsIndicesM rnc ri |
223 specialRoom <- io $ room'sM rnc isSpecial ri |
222 newMaster <- io $ client'sM rnc id newMasterId |
224 newMasterId <- liftM (\ids -> fromMaybe (listToMaybe . reverse . filter (/= ci) $ ids) $ liftM Just delegateId) . io $ roomClientsIndicesM rnc ri |
|
225 newMaster <- io $ client'sM rnc id `DT.mapM` newMasterId |
223 oldMasterId <- io $ room'sM rnc masterID ri |
226 oldMasterId <- io $ room'sM rnc masterID ri |
224 oldMaster <- io $ client'sM rnc id oldMasterId |
|
225 oldRoomName <- io $ room'sM rnc name ri |
227 oldRoomName <- io $ room'sM rnc name ri |
226 kicked <- client's isKickedFromServer |
228 kicked <- client's isKickedFromServer |
227 thisRoomChans <- liftM (map sendChan) $ roomClientsS ri |
229 thisRoomChans <- liftM (map sendChan) $ roomClientsS ri |
228 let newRoomName = if (proto < 42) || kicked then nick newMaster else oldRoomName |
230 let newRoomName = if ((proto < 42) || kicked) && (not specialRoom) then maybeNick newMaster else oldRoomName |
229 mapM_ processAction [ |
231 |
|
232 when (isJust oldMasterId) $ do |
|
233 oldMasterNick <- io $ client'sM rnc nick (fromJust oldMasterId) |
|
234 mapM_ processAction [ |
|
235 ModifyClient2 (fromJust oldMasterId) (\c -> c{isMaster = False}) |
|
236 , AnswerClients thisRoomChans ["CLIENT_FLAGS", "-h", oldMasterNick] |
|
237 ] |
|
238 |
|
239 when (isJust newMasterId) $ |
|
240 mapM_ processAction [ |
|
241 ModifyClient2 (fromJust newMasterId) (\c -> c{isMaster = True}) |
|
242 , AnswerClients [sendChan $ fromJust newMaster] ["ROOM_CONTROL_ACCESS", "1"] |
|
243 , AnswerClients thisRoomChans ["CLIENT_FLAGS", "+h", nick $ fromJust newMaster] |
|
244 ] |
|
245 |
|
246 processAction $ |
230 ModifyRoom (\r -> r{masterID = newMasterId |
247 ModifyRoom (\r -> r{masterID = newMasterId |
231 , name = newRoomName |
248 , name = newRoomName |
232 , isRestrictedJoins = False |
249 , isRestrictedJoins = False |
233 , isRestrictedTeams = False |
250 , isRestrictedTeams = False |
234 , isRegisteredOnly = False} |
251 , isRegisteredOnly = isSpecial r} |
235 ) |
252 ) |
236 , ModifyClient2 newMasterId (\c -> c{isMaster = True}) |
|
237 , ModifyClient2 oldMasterId (\c -> c{isMaster = False}) |
|
238 , AnswerClients [sendChan newMaster] ["ROOM_CONTROL_ACCESS", "1"] |
|
239 , AnswerClients thisRoomChans ["CLIENT_FLAGS", "-h", nick oldMaster] |
|
240 , AnswerClients thisRoomChans ["CLIENT_FLAGS", "+h", nick newMaster] |
|
241 ] |
|
242 |
253 |
243 newRoom' <- io $ room'sM rnc id ri |
254 newRoom' <- io $ room'sM rnc id ri |
244 chans <- liftM (map sendChan) $! sameProtoClientsS proto |
255 chans <- liftM (map sendChan) $! sameProtoClientsS proto |
245 processAction $ AnswerClients chans ("ROOM" : "UPD" : oldRoomName : roomInfo (nick newMaster) newRoom') |
256 processAction $ AnswerClients chans ("ROOM" : "UPD" : oldRoomName : roomInfo proto (maybeNick newMaster) newRoom') |
246 |
257 |
247 |
258 |
248 processAction (AddRoom roomName roomPassword) = do |
259 processAction (AddRoom roomName roomPassword) = do |
249 Just clId <- gets clientIndex |
260 Just clId <- gets clientIndex |
250 rnc <- gets roomsClients |
261 rnc <- gets roomsClients |
251 proto <- client's clientProto |
262 proto <- client's clientProto |
252 n <- client's nick |
263 n <- client's nick |
253 |
264 |
254 let rm = newRoom{ |
265 let rm = newRoom{ |
255 masterID = clId, |
266 masterID = Just clId, |
256 name = roomName, |
267 name = roomName, |
257 password = roomPassword, |
268 password = roomPassword, |
258 roomProto = proto |
269 roomProto = proto |
259 } |
270 } |
260 |
271 |
290 Just clId <- gets clientIndex |
301 Just clId <- gets clientIndex |
291 proto <- client's clientProto |
302 proto <- client's clientProto |
292 rnc <- gets roomsClients |
303 rnc <- gets roomsClients |
293 ri <- io $ clientRoomM rnc clId |
304 ri <- io $ clientRoomM rnc clId |
294 rm <- io $ room'sM rnc id ri |
305 rm <- io $ room'sM rnc id ri |
295 n <- io $ client'sM rnc nick (masterID rm) |
306 masterCl <- io $ client'sM rnc id `DT.mapM` (masterID rm) |
296 chans <- liftM (map sendChan) $! sameProtoClientsS proto |
307 chans <- liftM (map sendChan) $! sameProtoClientsS proto |
297 processAction $ AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo n rm) |
308 processAction $ AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo proto (maybeNick masterCl) rm) |
298 |
309 |
299 |
310 |
300 processAction UnreadyRoomClients = do |
311 processAction UnreadyRoomClients = do |
301 ri <- clientRoomA |
312 ri <- clientRoomA |
302 roomPlayers <- roomClientsS ri |
313 roomPlayers <- roomClientsS ri |
454 , ModifyClient (\c -> c{webPassword = p, isAdministrator = a, isContributor = contr}) |
463 , ModifyClient (\c -> c{webPassword = p, isAdministrator = a, isContributor = contr}) |
455 ] |
464 ] |
456 |
465 |
457 processAction JoinLobby = do |
466 processAction JoinLobby = do |
458 chan <- client's sendChan |
467 chan <- client's sendChan |
|
468 rnc <- gets roomsClients |
459 clientNick <- client's nick |
469 clientNick <- client's nick |
460 isAuthenticated <- liftM (not . B.null) $ client's webPassword |
470 isAuthenticated <- liftM (not . B.null) $ client's webPassword |
461 isAdmin <- client's isAdministrator |
471 isAdmin <- client's isAdministrator |
462 isContr <- client's isContributor |
472 isContr <- client's isContributor |
463 loggedInClients <- liftM (Prelude.filter isVisible) $! allClientsS |
473 loggedInClients <- liftM (Prelude.filter isVisible) $! allClientsS |
464 let (lobbyNicks, clientsChans) = unzip . L.map (nick &&& sendChan) $ loggedInClients |
474 let (lobbyNicks, clientsChans) = unzip . L.map (nick &&& sendChan) $ loggedInClients |
465 let authenticatedNicks = L.map nick . L.filter (not . B.null . webPassword) $ loggedInClients |
475 let authenticatedNicks = L.map nick . L.filter (not . B.null . webPassword) $ loggedInClients |
466 let adminsNicks = L.map nick . L.filter isAdministrator $ loggedInClients |
476 let adminsNicks = L.map nick . L.filter isAdministrator $ loggedInClients |
467 let contrNicks = L.map nick . L.filter isContributor $ loggedInClients |
477 let contrNicks = L.map nick . L.filter isContributor $ loggedInClients |
|
478 inRoomNicks <- io $ |
|
479 allClientsM rnc |
|
480 >>= filterM (liftM ((/=) lobbyId) . clientRoomM rnc) |
|
481 >>= mapM (client'sM rnc nick) |
468 let clFlags = B.concat . L.concat $ [["u" | isAuthenticated], ["a" | isAdmin], ["c" | isContr]] |
482 let clFlags = B.concat . L.concat $ [["u" | isAuthenticated], ["a" | isAdmin], ["c" | isContr]] |
469 mapM_ processAction . concat $ [ |
483 mapM_ processAction . concat $ [ |
470 [AnswerClients clientsChans ["LOBBY:JOINED", clientNick]] |
484 [AnswerClients clientsChans ["LOBBY:JOINED", clientNick]] |
471 , [AnswerClients [chan] ("LOBBY:JOINED" : clientNick : lobbyNicks)] |
485 , [AnswerClients [chan] ("LOBBY:JOINED" : clientNick : lobbyNicks)] |
472 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+u" : authenticatedNicks) | not $ null authenticatedNicks] |
486 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+u" : authenticatedNicks) | not $ null authenticatedNicks] |
473 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+a" : adminsNicks) | not $ null adminsNicks] |
487 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+a" : adminsNicks) | not $ null adminsNicks] |
474 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+c" : contrNicks) | not $ null contrNicks] |
488 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+c" : contrNicks) | not $ null contrNicks] |
|
489 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+i" : inRoomNicks) | not $ null inRoomNicks] |
475 , [AnswerClients (chan : clientsChans) ["CLIENT_FLAGS", B.concat["+" , clFlags], clientNick] | not $ B.null clFlags] |
490 , [AnswerClients (chan : clientsChans) ["CLIENT_FLAGS", B.concat["+" , clFlags], clientNick] | not $ B.null clFlags] |
476 , [ModifyClient (\cl -> cl{logonPassed = True, isVisible = True})] |
491 , [ModifyClient (\cl -> cl{logonPassed = True, isVisible = True})] |
477 , [SendServerMessage] |
492 , [SendServerMessage] |
478 ] |
493 ] |
479 |
494 |
676 |
691 |
677 |
692 |
678 processAction CheckRecord = do |
693 processAction CheckRecord = do |
679 p <- client's clientProto |
694 p <- client's clientProto |
680 c <- client's sendChan |
695 c <- client's sendChan |
681 (cinfo, l) <- io $ loadReplay (fromIntegral p) |
696 ri <- clientRoomA |
|
697 rnc <- gets roomsClients |
|
698 |
|
699 blackList <- liftM (map (recordFileName . fromJust . checkInfo) . filter (isJust . checkInfo)) allClientsS |
|
700 |
|
701 readyCheckersIds <- io $ do |
|
702 allci <- allClientsM rnc |
|
703 filterM (client'sM rnc (isJust . checkInfo)) allci |
|
704 |
|
705 (cinfo, l) <- io $ loadReplay (fromIntegral p) blackList |
682 when (not . null $ l) $ |
706 when (not . null $ l) $ |
683 mapM_ processAction [ |
707 mapM_ processAction [ |
684 AnswerClients [c] ("REPLAY" : l) |
708 AnswerClients [c] ("REPLAY" : l) |
685 , ModifyClient $ \c -> c{checkInfo = cinfo, isReady = False} |
709 , ModifyClient $ \c -> c{checkInfo = cinfo, isReady = False} |
686 ] |
710 ] |
691 io $ moveFailedRecord fileName |
715 io $ moveFailedRecord fileName |
692 |
716 |
693 |
717 |
694 processAction (CheckSuccess info) = do |
718 processAction (CheckSuccess info) = do |
695 Just (CheckInfo fileName teams) <- client's checkInfo |
719 Just (CheckInfo fileName teams) <- client's checkInfo |
|
720 p <- client's clientProto |
696 si <- gets serverInfo |
721 si <- gets serverInfo |
697 io $ writeChan (dbQueries si) $ StoreAchievements (B.pack fileName) (map toPair teams) info |
722 io $ writeChan (dbQueries si) $ StoreAchievements p (B.pack fileName) (map toPair teams) info |
698 io $ moveCheckedRecord fileName |
723 io $ moveCheckedRecord fileName |
699 where |
724 where |
700 toPair t = (teamname t, teamowner t) |
725 toPair t = (teamname t, teamowner t) |
701 |
726 |
702 processAction (QueryReplay name) = do |
727 processAction (QueryReplay rname) = do |
703 (Just ci) <- gets clientIndex |
728 (Just ci) <- gets clientIndex |
704 si <- gets serverInfo |
729 si <- gets serverInfo |
705 uid <- client's clUID |
730 uid <- client's clUID |
706 io $ writeChan (dbQueries si) $ GetReplayName ci (hashUnique uid) name |
731 io $ writeChan (dbQueries si) $ GetReplayName ci (hashUnique uid) rname |
707 |
732 |
708 #else |
733 #else |
709 processAction SaveReplay = return () |
734 processAction SaveReplay = return () |
710 processAction CheckRecord = return () |
735 processAction CheckRecord = return () |
711 processAction (CheckFailed _) = return () |
736 processAction (CheckFailed _) = return () |
712 processAction (CheckSuccess _) = return () |
737 processAction (CheckSuccess _) = return () |
713 processAction (QueryReplay _) = return () |
738 processAction (QueryReplay _) = return () |
714 #endif |
739 #endif |
715 |
740 |
716 processAction (ShowReplay name) = do |
741 processAction (ShowReplay rname) = do |
717 c <- client's sendChan |
742 c <- client's sendChan |
718 cl <- client's id |
743 cl <- client's id |
719 |
744 |
720 let fileName = B.concat ["checked/", if B.isPrefixOf "replays/" name then B.drop 8 name else name] |
745 let fileName = B.concat ["checked/", if B.isPrefixOf "replays/" rname then B.drop 8 rname else rname] |
721 |
746 |
722 checkInfo <- liftIO $ E.handle (\(e :: SomeException) -> |
747 cInfo <- liftIO $ E.handle (\(e :: SomeException) -> |
723 warningM "REPLAYS" (B.unpack $ B.concat ["Problems reading ", fileName, ": ", B.pack $ show e]) >> return Nothing) $ do |
748 warningM "REPLAYS" (B.unpack $ B.concat ["Problems reading ", fileName, ": ", B.pack $ show e]) >> return Nothing) $ do |
724 (t, p1, p2, msgs) <- liftM read $ readFile (B.unpack fileName) |
749 (t, p1, p2, msgs) <- liftM read $ readFile (B.unpack fileName) |
725 return $ Just (t, Map.fromList p1, Map.fromList p2, reverse msgs) |
750 return $ Just (t, Map.fromList p1, Map.fromList p2, reverse msgs) |
726 |
751 |
727 let (teams, params1, params2, roundMsgs) = fromJust checkInfo |
752 let (teams', params1, params2, roundMsgs') = fromJust cInfo |
728 |
753 |
729 when (isJust checkInfo) $ do |
754 when (isJust cInfo) $ do |
730 mapM_ processAction $ concat [ |
755 mapM_ processAction $ concat [ |
731 [AnswerClients [c] ["JOINED", nick cl]] |
756 [AnswerClients [c] ["JOINED", nick cl]] |
732 , answerFullConfigParams cl params1 params2 |
757 , answerFullConfigParams cl params1 params2 |
733 , answerAllTeams cl teams |
758 , answerAllTeams cl teams' |
734 , [AnswerClients [c] ["RUN_GAME"]] |
759 , [AnswerClients [c] ["RUN_GAME"]] |
735 , [AnswerClients [c] $ "EM" : roundMsgs] |
760 , [AnswerClients [c] $ "EM" : roundMsgs'] |
736 , [AnswerClients [c] ["KICKED"]] |
761 , [AnswerClients [c] ["KICKED"]] |
737 ] |
762 ] |