4 import Data.List |
4 import Data.List |
5 import Data.Word |
5 import Data.Word |
6 import Miscutils |
6 import Miscutils |
7 import Maybe (fromMaybe, fromJust) |
7 import Maybe (fromMaybe, fromJust) |
8 |
8 |
9 fromRoom :: String -> [ClientInfo] -> [ClientInfo] |
9 -- 'noInfo' clients state command handlers |
10 fromRoom roomName clients = filter (\cl -> roomName == room cl) clients |
10 handleCmd_noInfo :: Handle -> [ClientInfo] -> [RoomInfo] -> [String] -> ([ClientInfo], [RoomInfo], [Handle], [String]) |
11 |
11 |
12 -- 'noInfo' clients state command handlers |
12 handleCmd_noInfo clhandle clients rooms ("NICK":newNick:[]) = |
13 handleCmd_noInfo :: ClientInfo -> [ClientInfo] -> [RoomInfo] -> [String] -> (ClientInfo, [RoomInfo], [ClientInfo], [String]) |
|
14 |
|
15 handleCmd_noInfo client clients rooms ("NICK":newNick:[]) = |
|
16 if not . null $ nick client then |
13 if not . null $ nick client then |
17 (client, rooms, [client], ["ERROR", "The nick already chosen"]) |
14 (clients, rooms, [clhandle], ["ERROR", "The nick already chosen"]) |
18 else if haveSameNick then |
15 else if haveSameNick then |
19 (client, rooms, [client], ["WARNING", "Choose another nick"]) |
16 (clients, rooms, [clhandle], ["WARNING", "Choose another nick"]) |
20 else |
17 else |
21 (client{nick = newNick}, rooms, [client], ["NICK", newNick]) |
18 (modifyClient clhandle clients (\cl -> cl{nick = newNick}), rooms, [clhandle], ["NICK", newNick]) |
22 where |
19 where |
23 haveSameNick = not . null $ filter (\cl -> newNick == nick cl) clients |
20 haveSameNick = not . null $ filter (\cl -> newNick == nick cl) clients |
|
21 client = clientByHandle clhandle clients |
24 |
22 |
25 handleCmd_noInfo client clients rooms ("PROTO":protoNum:[]) = |
23 handleCmd_noInfo clhandle clients rooms ("PROTO":protoNum:[]) = |
26 if protocol client > 0 then |
24 if protocol client > 0 then |
27 (client, rooms, [client], ["ERROR", "Protocol number already known"]) |
25 (clients, rooms, [clhandle], ["ERROR", "Protocol number already known"]) |
28 else if parsedProto == 0 then |
26 else if parsedProto == 0 then |
29 (client, rooms, [client], ["ERROR", "Bad input"]) |
27 (clients, rooms, [clhandle], ["ERROR", "Bad input"]) |
30 else |
28 else |
31 (client{protocol = parsedProto}, rooms, [], []) |
29 (modifyClient clhandle clients (\cl -> cl{protocol = parsedProto}), rooms, [], []) |
32 where |
30 where |
33 parsedProto = fromMaybe 0 (maybeRead protoNum :: Maybe Word16) |
31 parsedProto = fromMaybe 0 (maybeRead protoNum :: Maybe Word16) |
|
32 client = clientByHandle clhandle clients |
34 |
33 |
35 |
34 handleCmd_noInfo clhandle clients rooms _ = (clients, rooms, [clhandle], ["ERROR", "Bad command or incorrect parameter"]) |
36 handleCmd_noInfo client _ rooms _ = (client, rooms, [client], ["ERROR", "Bad command or incorrect parameter"]) |
|
37 |
35 |
38 |
36 |
39 -- 'noRoom' clients state command handlers |
37 -- 'noRoom' clients state command handlers |
40 handleCmd_noRoom :: ClientInfo -> [ClientInfo] -> [RoomInfo] -> [String] -> (ClientInfo, [RoomInfo], [ClientInfo], [String]) |
38 handleCmd_noRoom :: Handle -> [ClientInfo] -> [RoomInfo] -> [String] -> ([ClientInfo], [RoomInfo], [Handle], [String]) |
41 |
39 |
42 handleCmd_noRoom client clients rooms ("CREATE":newRoom:roomPassword:[]) = |
40 {--handleCmd_noRoom clhandle clients rooms ("CREATE":newRoom:roomPassword:[]) = |
43 if haveSameRoom then |
41 if haveSameRoom then |
44 (client, rooms, [client], ["WARNING", "There's already a room with that name"]) |
42 (client, rooms, [clhandle], ["WARNING", "There's already a room with that name"]) |
45 else |
43 else |
46 (client{room = newRoom, isMaster = True}, (RoomInfo newRoom roomPassword):rooms, [client], ["JOINS", nick client]) |
44 (client{room = newRoom, isMaster = True}, (RoomInfo newRoom roomPassword):rooms, [client], ["JOINS", nick client]) |
47 where |
45 where |
48 haveSameRoom = not . null $ filter (\room -> newRoom == name room) rooms |
46 haveSameRoom = not . null $ filter (\room -> newRoom == name room) rooms |
49 |
47 |
50 handleCmd_noRoom client clients rooms ("CREATE":newRoom:[]) = |
48 handleCmd_noRoom clhandle clients rooms ("CREATE":newRoom:[]) = |
51 handleCmd_noRoom client clients rooms ["CREATE", newRoom, ""] |
49 handleCmd_noRoom client clients rooms ["CREATE", newRoom, ""] |
52 |
50 |
53 handleCmd_noRoom client clients rooms ("JOIN":roomName:roomPassword:[]) = |
51 handleCmd_noRoom clhandle clients rooms ("JOIN":roomName:roomPassword:[]) = |
54 if noRoom then |
52 if noRoom then |
55 (client, rooms, [client], ["WARNING", "There's no room with that name"]) |
53 (client, rooms, [clhandle], ["WARNING", "There's no room with that name"]) |
56 else if roomPassword /= password (getRoom roomName) then |
54 else if roomPassword /= password (getRoom roomName) then |
57 (client, rooms, [client], ["WARNING", "Wrong password"]) |
55 (client, rooms, [clhandle], ["WARNING", "Wrong password"]) |
58 else |
56 else |
59 (client{room = roomName}, rooms, client : fromRoom roomName clients, ["JOINS", nick client]) |
57 (client{room = roomName}, rooms, client : fromRoom roomName clients, ["JOINS", nick client]) |
60 where |
58 where |
61 noRoom = null $ filter (\room -> roomName == name room) rooms |
59 noRoom = null $ filter (\room -> roomName == name room) rooms |
62 getRoom roomName = fromJust $ find (\room -> roomName == name room) rooms |
60 getRoom roomName = fromJust $ find (\room -> roomName == name room) rooms |
63 |
61 |
64 handleCmd_noRoom client clients rooms ("JOIN":roomName:[]) = |
62 handleCmd_noRoom clhandle clients rooms ("JOIN":roomName:[]) = |
65 handleCmd_noRoom client clients rooms ["JOIN", ""] |
63 handleCmd_noRoom client clients rooms ["JOIN", ""]--} |
66 |
64 |
67 handleCmd_noRoom client _ rooms _ = (client, rooms, [client], ["ERROR", "Bad command or incorrect parameter"]) |
65 handleCmd_noRoom clhandle clients rooms _ = (clients, rooms, [clhandle], ["ERROR", "Bad command or incorrect parameter"]) |
68 |
66 |
69 -- 'inRoom' clients state command handlers |
67 -- 'inRoom' clients state command handlers |
70 handleCmd_inRoom :: ClientInfo -> [ClientInfo] -> [RoomInfo] -> [String] -> (ClientInfo, [RoomInfo], [ClientInfo], [String]) |
68 handleCmd_inRoom :: Handle -> [ClientInfo] -> [RoomInfo] -> [String] -> ([ClientInfo], [RoomInfo], [Handle], [String]) |
71 |
69 |
72 handleCmd_inRoom client _ rooms _ = (client, rooms, [client], ["ERROR", "Bad command or incorrect parameter"]) |
70 handleCmd_inRoom clhandle clients rooms _ = (clients, rooms, [clhandle], ["ERROR", "Bad command or incorrect parameter"]) |
73 |
71 |
74 -- state-independent command handlers |
72 -- state-independent command handlers |
75 handleCmd :: ClientInfo -> [ClientInfo] -> [RoomInfo] -> [String] -> (ClientInfo, [RoomInfo], [ClientInfo], [String]) |
73 handleCmd :: Handle -> [ClientInfo] -> [RoomInfo] -> [String] -> ([ClientInfo], [RoomInfo], [Handle], [String]) |
76 |
74 |
77 handleCmd client clients rooms ("QUIT":xs) = |
75 handleCmd clhandle clients rooms ("QUIT":xs) = |
78 if null (room client) then |
76 if null (room client) then |
79 (client, rooms, [client], ["QUIT"]) |
77 (clients, rooms, [clhandle], ["QUIT"]) |
80 else if isMaster client then |
78 else if isMaster client then |
81 (client, filter (\rm -> room client /= name rm) rooms, fromRoom (room client) clients, ["ROOMABANDONED"]) -- core disconnect clients on ROOMABANDONED command |
79 (clients, filter (\rm -> room client /= name rm) rooms, roomMates, ["ROOMABANDONED"]) -- core disconnects clients on ROOMABANDONED command |
82 else |
80 else |
83 (client, rooms, fromRoom (room client) clients, ["QUIT", nick client]) |
81 (clients, rooms, roomMates, ["QUIT", nick client]) |
|
82 where |
|
83 client = clientByHandle clhandle clients |
|
84 roomMates = fromRoomHandles (room client) clients |
84 |
85 |
85 -- check state and call state-dependent commmand handlers |
86 -- check state and call state-dependent commmand handlers |
86 handleCmd client clients rooms cmd = |
87 handleCmd clhandle clients rooms cmd = |
87 if null (nick client) || protocol client == 0 then |
88 if null (nick client) || protocol client == 0 then |
88 handleCmd_noInfo client clients rooms cmd |
89 handleCmd_noInfo clhandle clients rooms cmd |
89 else if null (room client) then |
90 else if null (room client) then |
90 handleCmd_noRoom client clients rooms cmd |
91 handleCmd_noRoom clhandle clients rooms cmd |
91 else |
92 else |
92 handleCmd_inRoom client clients rooms cmd |
93 handleCmd_inRoom clhandle clients rooms cmd |
|
94 where |
|
95 client = clientByHandle clhandle clients |