36 ModifyRoom (\r -> r{params = Map.insert paramName paramStrs (params r)}), |
36 ModifyRoom (\r -> r{params = Map.insert paramName paramStrs (params r)}), |
37 AnswerClients chans ("CFG" : paramName : paramStrs)] |
37 AnswerClients chans ("CFG" : paramName : paramStrs)] |
38 else |
38 else |
39 return [ProtocolError "Not room master"] |
39 return [ProtocolError "Not room master"] |
40 |
40 |
41 handleCmd_inRoom ("ADD_TEAM" : name : color : grave : fort : voicepack : flag : difStr : hhsInfo) |
41 handleCmd_inRoom ("ADD_TEAM" : tName : color : grave : fort : voicepack : flag : difStr : hhsInfo) |
42 | length hhsInfo /= 16 = return [ProtocolError "Corrupted hedgehogs info"] |
42 | length hhsInfo /= 16 = return [ProtocolError "Corrupted hedgehogs info"] |
43 | otherwise = do |
43 | otherwise = do |
44 (ci, rnc) <- ask |
44 (ci, _) <- ask |
45 r <- thisRoom |
45 rm <- thisRoom |
46 clNick <- clientNick |
46 clNick <- clientNick |
47 clChan <- thisClientChans |
47 clChan <- thisClientChans |
48 othersChans <- roomOthersChans |
48 othChans <- roomOthersChans |
49 return $ |
49 return $ |
50 if not . null . drop 5 $ teams r then |
50 if not . null . drop 5 $ teams rm then |
51 [Warning "too many teams"] |
51 [Warning "too many teams"] |
52 else if canAddNumber r <= 0 then |
52 else if canAddNumber rm <= 0 then |
53 [Warning "too many hedgehogs"] |
53 [Warning "too many hedgehogs"] |
54 else if isJust $ findTeam r then |
54 else if isJust $ findTeam rm then |
55 [Warning "There's already a team with same name in the list"] |
55 [Warning "There's already a team with same name in the list"] |
56 else if gameinprogress r then |
56 else if gameinprogress rm then |
57 [Warning "round in progress"] |
57 [Warning "round in progress"] |
58 else if isRestrictedTeams r then |
58 else if isRestrictedTeams rm then |
59 [Warning "restricted"] |
59 [Warning "restricted"] |
60 else |
60 else |
61 [ModifyRoom (\r -> r{teams = teams r ++ [newTeam ci clNick r]}), |
61 [ModifyRoom (\r -> r{teams = teams r ++ [newTeam ci clNick r]}), |
62 ModifyClient (\c -> c{teamsInGame = teamsInGame c + 1, clientClan = color}), |
62 ModifyClient (\c -> c{teamsInGame = teamsInGame c + 1, clientClan = color}), |
63 AnswerClients clChan ["TEAM_ACCEPTED", name], |
63 AnswerClients clChan ["TEAM_ACCEPTED", tName], |
64 AnswerClients othersChans $ teamToNet $ newTeam ci clNick r, |
64 AnswerClients othChans $ teamToNet $ newTeam ci clNick rm, |
65 AnswerClients othersChans ["TEAM_COLOR", name, color] |
65 AnswerClients othChans ["TEAM_COLOR", tName, color] |
66 ] |
66 ] |
67 where |
67 where |
68 canAddNumber r = 48 - (sum . map hhnum $ teams r) |
68 canAddNumber r = 48 - (sum . map hhnum $ teams r) |
69 findTeam = find (\t -> name == teamname t) . teams |
69 findTeam = find (\t -> tName == teamname t) . teams |
70 newTeam ci clNick r = (TeamInfo ci clNick name color grave fort voicepack flag difficulty (newTeamHHNum r) (hhsList hhsInfo)) |
70 newTeam ci clNick r = TeamInfo ci clNick tName color grave fort voicepack flag dif (newTeamHHNum r) (hhsList hhsInfo) |
71 difficulty = case B.readInt difStr of |
71 dif = case B.readInt difStr of |
72 Just (i, t) | B.null t -> fromIntegral i |
72 Just (i, t) | B.null t -> fromIntegral i |
73 otherwise -> 0 |
73 _ -> 0 |
74 hhsList [] = [] |
74 hhsList [] = [] |
75 hhsList [_] = error "Hedgehogs list with odd elements number" |
75 hhsList [_] = error "Hedgehogs list with odd elements number" |
76 hhsList (n:h:hhs) = HedgehogInfo n h : hhsList hhs |
76 hhsList (n:h:hhs) = HedgehogInfo n h : hhsList hhs |
77 newTeamHHNum r = min 4 (canAddNumber r) |
77 newTeamHHNum r = min 4 (canAddNumber r) |
78 |
78 |
79 handleCmd_inRoom ["REMOVE_TEAM", name] = do |
79 handleCmd_inRoom ["REMOVE_TEAM", tName] = do |
80 (ci, rnc) <- ask |
80 (ci, _) <- ask |
81 r <- thisRoom |
81 r <- thisRoom |
82 clNick <- clientNick |
82 clNick <- clientNick |
83 |
83 |
84 let maybeTeam = findTeam r |
84 let maybeTeam = findTeam r |
85 let team = fromJust maybeTeam |
85 let team = fromJust maybeTeam |
88 if isNothing $ findTeam r then |
88 if isNothing $ findTeam r then |
89 [Warning "REMOVE_TEAM: no such team"] |
89 [Warning "REMOVE_TEAM: no such team"] |
90 else if clNick /= teamowner team then |
90 else if clNick /= teamowner team then |
91 [ProtocolError "Not team owner!"] |
91 [ProtocolError "Not team owner!"] |
92 else |
92 else |
93 [RemoveTeam name, |
93 [RemoveTeam tName, |
94 ModifyClient |
94 ModifyClient |
95 (\c -> c{ |
95 (\c -> c{ |
96 teamsInGame = teamsInGame c - 1, |
96 teamsInGame = teamsInGame c - 1, |
97 clientClan = if teamsInGame c == 1 then undefined else anotherTeamClan ci r |
97 clientClan = if teamsInGame c == 1 then undefined else anotherTeamClan ci r |
98 }) |
98 }) |
99 ] |
99 ] |
100 where |
100 where |
101 anotherTeamClan ci = teamcolor . fromJust . find (\t -> teamownerId t == ci) . teams |
101 anotherTeamClan ci = teamcolor . fromJust . find (\t -> teamownerId t == ci) . teams |
102 findTeam = find (\t -> name == teamname t) . teams |
102 findTeam = find (\t -> tName == teamname t) . teams |
103 |
103 |
104 |
104 |
105 handleCmd_inRoom ["HH_NUM", teamName, numberStr] = do |
105 handleCmd_inRoom ["HH_NUM", teamName, numberStr] = do |
106 cl <- thisClient |
106 cl <- thisClient |
107 others <- roomOthersChans |
107 others <- roomOthersChans |
111 let team = fromJust maybeTeam |
111 let team = fromJust maybeTeam |
112 |
112 |
113 return $ |
113 return $ |
114 if not $ isMaster cl then |
114 if not $ isMaster cl then |
115 [ProtocolError "Not room master"] |
115 [ProtocolError "Not room master"] |
116 else if hhNumber < 1 || hhNumber > 8 || isNothing maybeTeam || hhNumber > (canAddNumber r) + (hhnum team) then |
116 else if hhNumber < 1 || hhNumber > 8 || isNothing maybeTeam || hhNumber > canAddNumber r + hhnum team then |
117 [] |
117 [] |
118 else |
118 else |
119 [ModifyRoom $ modifyTeam team{hhnum = hhNumber}, |
119 [ModifyRoom $ modifyTeam team{hhnum = hhNumber}, |
120 AnswerClients others ["HH_NUM", teamName, B.pack $ show hhNumber]] |
120 AnswerClients others ["HH_NUM", teamName, B.pack $ show hhNumber]] |
121 where |
121 where |
122 hhNumber = case B.readInt numberStr of |
122 hhNumber = case B.readInt numberStr of |
123 Just (i, t) | B.null t -> fromIntegral i |
123 Just (i, t) | B.null t -> fromIntegral i |
124 otherwise -> 0 |
124 _ -> 0 |
125 findTeam = find (\t -> teamName == teamname t) . teams |
125 findTeam = find (\t -> teamName == teamname t) . teams |
126 canAddNumber = (-) 48 . sum . map hhnum . teams |
126 canAddNumber = (-) 48 . sum . map hhnum . teams |
127 |
127 |
128 |
128 |
129 |
129 |
182 enoughClans = not . null . drop 1 . group . map teamcolor . teams |
182 enoughClans = not . null . drop 1 . group . map teamcolor . teams |
183 |
183 |
184 |
184 |
185 handleCmd_inRoom ["EM", msg] = do |
185 handleCmd_inRoom ["EM", msg] = do |
186 cl <- thisClient |
186 cl <- thisClient |
187 r <- thisRoom |
187 rm <- thisRoom |
188 chans <- roomOthersChans |
188 chans <- roomOthersChans |
189 |
189 |
190 if (teamsInGame cl > 0) && (gameinprogress r) && isLegal then |
190 if teamsInGame cl > 0 && gameinprogress rm && isLegal then |
191 return $ (AnswerClients chans ["EM", msg]) : [ModifyRoom (\r -> r{roundMsgs = roundMsgs r |> msg}) | not isKeepAlive] |
191 return $ AnswerClients chans ["EM", msg] : [ModifyRoom (\r -> r{roundMsgs = roundMsgs r |> msg}) | not isKeepAlive] |
192 else |
192 else |
193 return [] |
193 return [] |
194 where |
194 where |
195 (isLegal, isKeepAlive) = checkNetCmd msg |
195 (isLegal, isKeepAlive) = checkNetCmd msg |
196 |
196 |
197 |
197 |
198 handleCmd_inRoom ["ROUNDFINISHED", _] = do |
198 handleCmd_inRoom ["ROUNDFINISHED", _] = do |
199 cl <- thisClient |
199 cl <- thisClient |
200 r <- thisRoom |
200 rm <- thisRoom |
201 chans <- roomClientsChans |
201 chans <- roomClientsChans |
202 |
202 |
203 if isMaster cl && (gameinprogress r) then |
203 if isMaster cl && gameinprogress rm then |
204 return $ (ModifyRoom |
204 return $ ModifyRoom |
205 (\r -> r{ |
205 (\r -> r{ |
206 gameinprogress = False, |
206 gameinprogress = False, |
207 readyPlayers = 0, |
207 readyPlayers = 0, |
208 roundMsgs = empty, |
208 roundMsgs = empty, |
209 leftTeams = [], |
209 leftTeams = [], |
210 teamsAtStart = []} |
210 teamsAtStart = []} |
211 )) |
211 ) |
212 : UnreadyRoomClients |
212 : UnreadyRoomClients |
213 : answerRemovedTeams chans r |
213 : answerRemovedTeams chans rm |
214 else |
214 else |
215 return [] |
215 return [] |
216 where |
216 where |
217 answerRemovedTeams chans = map (\t -> AnswerClients chans ["REMOVE_TEAM", t]) . leftTeams |
217 answerRemovedTeams chans = map (\t -> AnswerClients chans ["REMOVE_TEAM", t]) . leftTeams |
218 |
218 |
237 handleCmd_inRoom ["KICK", kickNick] = do |
237 handleCmd_inRoom ["KICK", kickNick] = do |
238 (thisClientId, rnc) <- ask |
238 (thisClientId, rnc) <- ask |
239 maybeClientId <- clientByNick kickNick |
239 maybeClientId <- clientByNick kickNick |
240 master <- liftM isMaster thisClient |
240 master <- liftM isMaster thisClient |
241 let kickId = fromJust maybeClientId |
241 let kickId = fromJust maybeClientId |
242 let sameRoom = (clientRoom rnc thisClientId) == (clientRoom rnc kickId) |
242 let sameRoom = clientRoom rnc thisClientId == clientRoom rnc kickId |
243 return |
243 return |
244 [KickRoomClient kickId | master && isJust maybeClientId && (kickId /= thisClientId) && sameRoom] |
244 [KickRoomClient kickId | master && isJust maybeClientId && (kickId /= thisClientId) && sameRoom] |
245 |
245 |
246 |
246 |
247 handleCmd_inRoom ["TEAMCHAT", msg] = do |
247 handleCmd_inRoom ["TEAMCHAT", msg] = do |
248 cl <- thisClient |
248 cl <- thisClient |
249 chans <- roomSameClanChans |
249 chans <- roomSameClanChans |
250 return [AnswerClients chans ["EM", engineMsg cl]] |
250 return [AnswerClients chans ["EM", engineMsg cl]] |
251 where |
251 where |
252 engineMsg cl = toEngineMsg $ "b" `B.append` (nick cl) `B.append` "(team): " `B.append` msg `B.append` "\x20\x20" |
252 engineMsg cl = toEngineMsg $ "b" `B.append` nick cl `B.append` "(team): " `B.append` msg `B.append` "\x20\x20" |
253 |
253 |
254 handleCmd_inRoom _ = return [ProtocolError "Incorrect command (state: in room)"] |
254 handleCmd_inRoom _ = return [ProtocolError "Incorrect command (state: in room)"] |