diff -r 5be338fa4e2c -r 596b1dcdc1df netserver/HWProto.hs --- a/netserver/HWProto.hs Tue Jul 15 16:40:50 2008 +0000 +++ b/netserver/HWProto.hs Mon Jul 21 09:45:40 2008 +0000 @@ -6,94 +6,85 @@ import Miscutils import Maybe (fromMaybe, fromJust) --- 'noInfo' clients state command handlers -handleCmd_noInfo :: Handle -> [ClientInfo] -> [RoomInfo] -> [String] -> ([ClientInfo], [RoomInfo], [Handle], [String]) +-- Main state-independent cmd handler +handleCmd :: CmdHandler +handleCmd client _ rooms ("QUIT":xs) = + if null (room client) then + (noChangeClients, noChangeRooms, clientOnly, ["QUIT"]) + else if isMaster client then + (noChangeClients, removeRoom (room client), sameRoom, ["ROOMABANDONED"]) -- core disconnects clients on ROOMABANDONED command + else + (noChangeClients, noChangeRooms, sameRoom, ["QUIT", nick client]) -handleCmd_noInfo clhandle clients rooms ("NICK":newNick:[]) = +-- check state and call state-dependent commmand handlers +handleCmd client clients rooms cmd = + if null (nick client) || protocol client == 0 then + handleCmd_noInfo client clients rooms cmd + else if null (room client) then + handleCmd_noRoom client clients rooms cmd + else + handleCmd_inRoom client clients rooms cmd + +-- 'no info' state - need to get protocol number and nickname +handleCmd_noInfo :: CmdHandler +handleCmd_noInfo client clients _ ["NICK", newNick] = if not . null $ nick client then - (clients, rooms, [clhandle], ["ERROR", "The nick already chosen"]) + (noChangeClients, noChangeRooms, clientOnly, ["ERROR", "The nick already chosen"]) else if haveSameNick then - (clients, rooms, [clhandle], ["WARNING", "Choose another nick"]) + (noChangeClients, noChangeRooms, clientOnly, ["WARNING", "Choose another nick"]) else - (modifyClient clhandle clients (\cl -> cl{nick = newNick}), rooms, [clhandle], ["NICK", newNick]) + (modifyClient client{nick = newNick}, noChangeRooms, clientOnly, ["NICK", newNick]) where haveSameNick = not . null $ filter (\cl -> newNick == nick cl) clients - client = clientByHandle clhandle clients -handleCmd_noInfo clhandle clients rooms ("PROTO":protoNum:[]) = +handleCmd_noInfo client _ _ ["PROTO", protoNum] = if protocol client > 0 then - (clients, rooms, [clhandle], ["ERROR", "Protocol number already known"]) + (noChangeClients, noChangeRooms, clientOnly, ["ERROR", "Protocol number already known"]) else if parsedProto == 0 then - (clients, rooms, [clhandle], ["ERROR", "Bad input"]) + (noChangeClients, noChangeRooms, clientOnly, ["ERROR", "Bad input"]) else - (modifyClient clhandle clients (\cl -> cl{protocol = parsedProto}), rooms, [], []) + (modifyClient client{protocol = parsedProto}, noChangeRooms, clientOnly, ["PROTO", show parsedProto]) where parsedProto = fromMaybe 0 (maybeRead protoNum :: Maybe Word16) - client = clientByHandle clhandle clients -handleCmd_noInfo clhandle clients rooms _ = (clients, rooms, [clhandle], ["ERROR", "Bad command or incorrect parameter"]) - +handleCmd_noInfo _ _ _ _ = (noChangeClients, noChangeRooms, clientOnly, badCmd) -- 'noRoom' clients state command handlers -handleCmd_noRoom :: Handle -> [ClientInfo] -> [RoomInfo] -> [String] -> ([ClientInfo], [RoomInfo], [Handle], [String]) - -handleCmd_noRoom clhandle clients rooms ("LIST":[]) = - (clients, rooms, [clhandle], ["ROOMS"] ++ map (\r -> name r) rooms) +handleCmd_noRoom :: CmdHandler +handleCmd_noRoom client _ rooms ["LIST"] = + (noChangeClients, noChangeRooms, clientOnly, ["ROOMS"] ++ map name rooms) -handleCmd_noRoom clhandle clients rooms ("CREATE":newRoom:roomPassword:[]) = +handleCmd_noRoom client _ rooms ["CREATE", newRoom, roomPassword] = if haveSameRoom then - (clients, rooms, [clhandle], ["WARNING", "There's already a room with that name"]) + (noChangeClients, noChangeRooms, clientOnly, ["WARNING", "There's already a room with that name"]) else - (modifyClient clhandle clients (\cl -> cl{room = newRoom, isMaster = True}), (RoomInfo newRoom roomPassword):rooms, [clhandle], ["JOINS", nick client]) + (modifyClient client{room = newRoom, isMaster = True}, addRoom (RoomInfo newRoom roomPassword), clientOnly, ["JOINED", nick client]) where haveSameRoom = not . null $ filter (\room -> newRoom == name room) rooms - client = clientByHandle clhandle clients -handleCmd_noRoom clhandle clients rooms ("CREATE":newRoom:[]) = - handleCmd_noRoom clhandle clients rooms ["CREATE", newRoom, ""] - -handleCmd_noRoom clhandle clients rooms ("JOIN":roomName:roomPassword:[]) = +handleCmd_noRoom client clients rooms ["CREATE", newRoom] = + handleCmd_noRoom client clients rooms ["CREATE", newRoom, ""] + +handleCmd_noRoom client _ rooms ["JOIN", roomName, roomPassword] = if noSuchRoom then - (clients, rooms, [clhandle], ["WARNING", "There's no room with that name"]) + (noChangeClients, noChangeRooms, clientOnly, ["WARNING", "There's no room with that name"]) else if roomPassword /= password (roomByName roomName rooms) then - (clients, rooms, [clhandle], ["WARNING", "Wrong password"]) + (noChangeClients, noChangeRooms, clientOnly, ["WARNING", "Wrong password"]) else - (modifyClient clhandle clients (\cl -> cl{room = roomName}), rooms, clhandle : (fromRoomHandles roomName clients), ["JOINS", nick client]) + (modifyClient client{room = roomName}, noChangeRooms, fromRoom roomName, ["JOINED", nick client]) where noSuchRoom = null $ filter (\room -> roomName == name room) rooms - client = clientByHandle clhandle clients -handleCmd_noRoom clhandle clients rooms ("JOIN":roomName:[]) = - handleCmd_noRoom clhandle clients rooms ["JOIN", roomName, ""] +handleCmd_noRoom client clients rooms ["JOIN", roomName] = + handleCmd_noRoom client clients rooms ["JOIN", roomName, ""] -handleCmd_noRoom clhandle clients rooms _ = (clients, rooms, [clhandle], ["ERROR", "Bad command or incorrect parameter"]) +handleCmd_noRoom _ _ _ _ = (noChangeClients, noChangeRooms, clientOnly, badCmd) -- 'inRoom' clients state command handlers -handleCmd_inRoom :: Handle -> [ClientInfo] -> [RoomInfo] -> [String] -> ([ClientInfo], [RoomInfo], [Handle], [String]) +handleCmd_inRoom :: CmdHandler -handleCmd_inRoom clhandle clients rooms _ = (clients, rooms, [clhandle], ["ERROR", "Bad command or incorrect parameter"]) - --- state-independent command handlers -handleCmd :: Handle -> [ClientInfo] -> [RoomInfo] -> [String] -> ([ClientInfo], [RoomInfo], [Handle], [String]) +handleCmd_inRoom client _ _ ["CHAT_STRING", _, msg] = (noChangeClients, noChangeRooms, othersInRoom, ["CHAT_STRING", nick client, msg]) -handleCmd clhandle clients rooms ("QUIT":xs) = - if null (room client) then - (clients, rooms, [clhandle], ["QUIT"]) - else if isMaster client then - (clients, filter (\rm -> room client /= name rm) rooms, roomMates, ["ROOMABANDONED"]) -- core disconnects clients on ROOMABANDONED command - else - (clients, rooms, roomMates, ["QUIT", nick client]) - where - client = clientByHandle clhandle clients - roomMates = fromRoomHandles (room client) clients +handleCmd_inRoom client clients rooms ["CONFIG_PARAM", paramName, value] = (noChangeClients, noChangeRooms, othersInRoom, ["CONFIG_PARAM", paramName, value]) --- check state and call state-dependent commmand handlers -handleCmd clhandle clients rooms cmd = - if null (nick client) || protocol client == 0 then - handleCmd_noInfo clhandle clients rooms cmd - else if null (room client) then - handleCmd_noRoom clhandle clients rooms cmd - else - handleCmd_inRoom clhandle clients rooms cmd - where - client = clientByHandle clhandle clients +handleCmd_inRoom _ _ _ _ = (noChangeClients, noChangeRooms, clientOnly, badCmd)