418 return () |
419 return () |
419 |
420 |
420 |
421 |
421 processAction (ProcessAccountInfo info) = do |
422 processAction (ProcessAccountInfo info) = do |
422 case info of |
423 case info of |
423 HasAccount passwd isAdmin -> do |
424 HasAccount passwd isAdmin isContr -> do |
424 b <- isBanned |
425 b <- isBanned |
425 c <- client's isChecker |
426 c <- client's isChecker |
426 when (not b) $ (if c then checkerLogin else playerLogin) passwd isAdmin |
427 when (not b) $ (if c then checkerLogin else playerLogin) passwd isAdmin isContr |
427 Guest -> do |
428 Guest -> do |
428 b <- isBanned |
429 b <- isBanned |
429 c <- client's isChecker |
430 c <- client's isChecker |
430 when (not b) $ |
431 when (not b) $ |
431 if c then |
432 if c then |
432 checkerLogin "" False |
433 checkerLogin "" False False |
433 else |
434 else |
434 processAction JoinLobby |
435 processAction JoinLobby |
435 Admin -> do |
436 Admin -> do |
436 mapM_ processAction [ModifyClient (\cl -> cl{isAdministrator = True}), JoinLobby] |
437 mapM_ processAction [ModifyClient (\cl -> cl{isAdministrator = True}), JoinLobby] |
437 chan <- client's sendChan |
438 chan <- client's sendChan |
438 processAction $ AnswerClients [chan] ["ADMIN_ACCESS"] |
439 processAction $ AnswerClients [chan] ["ADMIN_ACCESS"] |
|
440 ReplayName fn -> processAction $ ShowReplay fn |
439 where |
441 where |
440 isBanned = do |
442 isBanned = do |
441 processAction $ CheckBanned False |
443 processAction $ CheckBanned False |
442 liftM B.null $ client's nick |
444 liftM B.null $ client's nick |
443 checkerLogin _ False = processAction $ ByeClient $ loc "No checker rights" |
445 checkerLogin _ False _ = processAction $ ByeClient $ loc "No checker rights" |
444 checkerLogin p True = do |
446 checkerLogin p True _ = do |
445 wp <- client's webPassword |
447 wp <- client's webPassword |
446 processAction $ |
448 processAction $ |
447 if wp == p then ModifyClient $ \c -> c{logonPassed = True} else ByeClient $ loc "Authentication failed" |
449 if wp == p then ModifyClient $ \c -> c{logonPassed = True} else ByeClient $ loc "Authentication failed" |
448 playerLogin p a = do |
450 playerLogin p a contr = do |
449 chan <- client's sendChan |
451 chan <- client's sendChan |
450 mapM_ processAction [AnswerClients [chan] ["ASKPASSWORD"], ModifyClient (\c -> c{webPassword = p, isAdministrator = a})] |
452 mapM_ processAction [ |
|
453 AnswerClients [chan] ["ASKPASSWORD"] |
|
454 , ModifyClient (\c -> c{webPassword = p, isAdministrator = a, isContributor = contr}) |
|
455 ] |
451 |
456 |
452 processAction JoinLobby = do |
457 processAction JoinLobby = do |
453 chan <- client's sendChan |
458 chan <- client's sendChan |
454 clientNick <- client's nick |
459 clientNick <- client's nick |
455 isAuthenticated <- liftM (not . B.null) $ client's webPassword |
460 isAuthenticated <- liftM (not . B.null) $ client's webPassword |
456 isAdmin <- client's isAdministrator |
461 isAdmin <- client's isAdministrator |
|
462 isContr <- client's isContributor |
457 loggedInClients <- liftM (Prelude.filter isVisible) $! allClientsS |
463 loggedInClients <- liftM (Prelude.filter isVisible) $! allClientsS |
458 let (lobbyNicks, clientsChans) = unzip . L.map (nick &&& sendChan) $ loggedInClients |
464 let (lobbyNicks, clientsChans) = unzip . L.map (nick &&& sendChan) $ loggedInClients |
459 let authenticatedNicks = L.map nick . L.filter (not . B.null . webPassword) $ loggedInClients |
465 let authenticatedNicks = L.map nick . L.filter (not . B.null . webPassword) $ loggedInClients |
460 let adminsNicks = L.map nick . L.filter isAdministrator $ loggedInClients |
466 let adminsNicks = L.map nick . L.filter isAdministrator $ loggedInClients |
461 let clFlags = B.concat . L.concat $ [["u" | isAuthenticated], ["a" | isAdmin]] |
467 let contrNicks = L.map nick . L.filter isContributor $ loggedInClients |
|
468 let clFlags = B.concat . L.concat $ [["u" | isAuthenticated], ["a" | isAdmin], ["c" | isContr]] |
462 mapM_ processAction . concat $ [ |
469 mapM_ processAction . concat $ [ |
463 [AnswerClients clientsChans ["LOBBY:JOINED", clientNick]] |
470 [AnswerClients clientsChans ["LOBBY:JOINED", clientNick]] |
464 , [AnswerClients [chan] ("LOBBY:JOINED" : clientNick : lobbyNicks)] |
471 , [AnswerClients [chan] ("LOBBY:JOINED" : clientNick : lobbyNicks)] |
465 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+u" : authenticatedNicks) | not $ null authenticatedNicks] |
472 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+u" : authenticatedNicks) | not $ null authenticatedNicks] |
466 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+a" : adminsNicks) | not $ null adminsNicks] |
473 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+a" : adminsNicks) | not $ null adminsNicks] |
|
474 , [AnswerClients [chan] ("CLIENT_FLAGS" : "+c" : contrNicks) | not $ null contrNicks] |
467 , [AnswerClients (chan : clientsChans) ["CLIENT_FLAGS", B.concat["+" , clFlags], clientNick] | not $ B.null clFlags] |
475 , [AnswerClients (chan : clientsChans) ["CLIENT_FLAGS", B.concat["+" , clFlags], clientNick] | not $ B.null clFlags] |
468 , [ModifyClient (\cl -> cl{logonPassed = True, isVisible = True})] |
476 , [ModifyClient (\cl -> cl{logonPassed = True, isVisible = True})] |
469 , [SendServerMessage] |
477 , [SendServerMessage] |
470 ] |
478 ] |
471 |
479 |
648 #if defined(OFFICIAL_SERVER) |
658 #if defined(OFFICIAL_SERVER) |
649 processAction SaveReplay = do |
659 processAction SaveReplay = do |
650 ri <- clientRoomA |
660 ri <- clientRoomA |
651 rnc <- gets roomsClients |
661 rnc <- gets roomsClients |
652 |
662 |
653 io $ do |
663 readyCheckersIds <- io $ do |
654 r <- room'sM rnc id ri |
664 r <- room'sM rnc id ri |
655 saveReplay r |
665 saveReplay r |
|
666 allci <- allClientsM rnc |
|
667 filterM (client'sM rnc isReadyChecker) allci |
|
668 |
|
669 when (not $ null readyCheckersIds) $ do |
|
670 oldci <- gets clientIndex |
|
671 withStateT (\s -> s{clientIndex = Just $ head readyCheckersIds}) |
|
672 $ processAction CheckRecord |
|
673 modify (\s -> s{clientIndex = oldci}) |
|
674 where |
|
675 isReadyChecker cl = isChecker cl && isReady cl |
656 |
676 |
657 |
677 |
658 processAction CheckRecord = do |
678 processAction CheckRecord = do |
659 p <- client's clientProto |
679 p <- client's clientProto |
660 c <- client's sendChan |
680 c <- client's sendChan |
661 (cinfo, l) <- io $ loadReplay (fromIntegral p) |
681 (cinfo, l) <- io $ loadReplay (fromIntegral p) |
662 when (not . null $ l) $ |
682 when (not . null $ l) $ |
663 mapM_ processAction [ |
683 mapM_ processAction [ |
664 AnswerClients [c] ("REPLAY" : l) |
684 AnswerClients [c] ("REPLAY" : l) |
665 , ModifyClient $ \c -> c{checkInfo = cinfo} |
685 , ModifyClient $ \c -> c{checkInfo = cinfo, isReady = False} |
666 ] |
686 ] |
|
687 |
667 |
688 |
668 processAction (CheckFailed msg) = do |
689 processAction (CheckFailed msg) = do |
669 Just (CheckInfo fileName _) <- client's checkInfo |
690 Just (CheckInfo fileName _) <- client's checkInfo |
670 io $ moveFailedRecord fileName |
691 io $ moveFailedRecord fileName |
671 |
692 |
|
693 |
672 processAction (CheckSuccess info) = do |
694 processAction (CheckSuccess info) = do |
673 Just (CheckInfo fileName _) <- client's checkInfo |
695 Just (CheckInfo fileName teams) <- client's checkInfo |
|
696 si <- gets serverInfo |
|
697 io $ writeChan (dbQueries si) $ StoreAchievements (B.pack fileName) (map toPair teams) info |
674 io $ moveCheckedRecord fileName |
698 io $ moveCheckedRecord fileName |
|
699 where |
|
700 toPair t = (teamname t, teamowner t) |
|
701 |
|
702 processAction (QueryReplay name) = do |
|
703 (Just ci) <- gets clientIndex |
|
704 si <- gets serverInfo |
|
705 uid <- client's clUID |
|
706 io $ writeChan (dbQueries si) $ GetReplayName ci (hashUnique uid) name |
675 |
707 |
676 #else |
708 #else |
677 processAction SaveReplay = return () |
709 processAction SaveReplay = return () |
678 processAction CheckRecord = return () |
710 processAction CheckRecord = return () |
679 processAction (CheckFailed _) = return () |
711 processAction (CheckFailed _) = return () |
680 processAction (CheckSuccess _) = return () |
712 processAction (CheckSuccess _) = return () |
|
713 processAction (QueryReplay _) = return () |
681 #endif |
714 #endif |
|
715 |
|
716 processAction (ShowReplay name) = do |
|
717 c <- client's sendChan |
|
718 cl <- client's id |
|
719 |
|
720 let fileName = B.concat ["checked/", if B.isPrefixOf "replays/" name then B.drop 8 name else name] |
|
721 |
|
722 checkInfo <- liftIO $ E.handle (\(e :: SomeException) -> |
|
723 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) |
|
725 return $ Just (t, Map.fromList p1, Map.fromList p2, reverse msgs) |
|
726 |
|
727 let (teams, params1, params2, roundMsgs) = fromJust checkInfo |
|
728 |
|
729 when (isJust checkInfo) $ do |
|
730 mapM_ processAction $ concat [ |
|
731 [AnswerClients [c] ["JOINED", nick cl]] |
|
732 , answerFullConfigParams cl params1 params2 |
|
733 , answerAllTeams cl teams |
|
734 , [AnswerClients [c] ["RUN_GAME"]] |
|
735 , [AnswerClients [c] $ "EM" : roundMsgs] |
|
736 , [AnswerClients [c] ["KICKED"]] |
|
737 ] |