diff options
Diffstat (limited to 'src/Reaktor/IRC.hs')
-rw-r--r-- | src/Reaktor/IRC.hs | 450 |
1 files changed, 450 insertions, 0 deletions
diff --git a/src/Reaktor/IRC.hs b/src/Reaktor/IRC.hs new file mode 100644 index 0000000..325374d --- /dev/null +++ b/src/Reaktor/IRC.hs @@ -0,0 +1,450 @@ +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE OverloadedStrings #-} +module Reaktor.IRC + ( Command(..) + ) where + +import Data.Aeson +import Data.Aeson.Types (typeMismatch) +import qualified Data.HashMap.Lazy as M +import Data.Hashable (Hashable) +import Data.String.Conversions +import qualified Data.Text.Extended as T +import qualified Data.Text.Read as T +import GHC.Generics (Generic) +import Prelude.Extended + +data Command = + UnknownCommand Text | UnknownReply Int + | ADMIN + | AWAY + | CONNECT + | DIE + | ERROR + | INFO + | INVITE + | ISON + | JOIN + | KICK + | KILL + | LINKS + | LIST + | LUSERS + | MODE + | MOTD + | NAMES + | NICK + | NJOIN + | NOTICE + | OPER + | PART + | PASS + | PING + | PONG + | PRIVMSG + | QUIT + | REHASH + | RESTART + | SERVER + | SERVICE + | SERVLIST + | SQUERY + | SQUIRT + | SQUIT + | STATS + | SUMMON + | TIME + | TOPIC + | TRACE + | USER + | USERHOST + | USERS + | VERSION + | WALLOPS + | WHO + | WHOIS + | WHOWAS + + | RPL_WELCOME + | RPL_YOURHOST + | RPL_CREATED + | RPL_MYINFO + | RPL_BOUNCE + + | RPL_TRACELINK + | RPL_TRACECONNECTING + | RPL_TRACEHANDSHAKE + | RPL_TRACEUNKNOWN + | RPL_TRACEOPERATOR + | RPL_TRACEUSER + | RPL_TRACESERVER + | RPL_TRACESERVICE + | RPL_TRACENEWTYPE + | RPL_TRACECLASS + | RPL_TRACERECONNECT + | RPL_STATSLINKINFO + | RPL_STATSCOMMANDS + | RPL_ENDOFSTATS + | RPL_UMODEIS + | RPL_SERVLIST + | RPL_SERVLISTEND + | RPL_STATSUPTIME + | RPL_STATSOLINE + | RPL_LUSERCLIENT + | RPL_LUSEROP + | RPL_LUSERUNKNOWN + | RPL_LUSERCHANNELS + | RPL_LUSERME + | RPL_ADMINME + | RPL_ADMINLOC1 + | RPL_ADMINLOC2 + | RPL_ADMINEMAIL + | RPL_TRACELOG + | RPL_TRACEEND + | RPL_TRYAGAIN + | RPL_AWAY + | RPL_USERHOST + | RPL_ISON + | RPL_UNAWAY + | RPL_NOWAWAY + | RPL_WHOISUSER + | RPL_WHOISSERVER + | RPL_WHOISOPERATOR + | RPL_WHOWASUSER + | RPL_ENDOFWHO + | RPL_WHOISIDLE + | RPL_ENDOFWHOIS + | RPL_WHOISCHANNELS + | RPL_LISTSTART + | RPL_LIST + | RPL_LISTEND + | RPL_CHANNELMODEIS + | RPL_UNIQOPIS + | RPL_NOTOPIC + | RPL_TOPIC + | RPL_INVITING + | RPL_SUMMONING + | RPL_INVITELIST + | RPL_ENDOFINVITELIST + | RPL_EXCEPTLIST + | RPL_ENDOFEXCEPTLIST + | RPL_VERSION + | RPL_WHOREPLY + | RPL_NAMREPLY + | RPL_LINKS + | RPL_ENDOFLINKS + | RPL_ENDOFNAMES + | RPL_BANLIST + | RPL_ENDOFBANLIST + | RPL_ENDOFWHOWAS + | RPL_INFO + | RPL_MOTD + | RPL_ENDOFINFO + | RPL_MOTDSTART + | RPL_ENDOFMOTD + | RPL_YOUREOPER + | RPL_REHASHING + | RPL_YOURESERVICE + | RPL_TIME + | RPL_USERSSTART + | RPL_USERS + | RPL_ENDOFUSERS + | RPL_NOUSERS + + | ERR_NOSUCHNICK + | ERR_NOSUCHSERVER + | ERR_NOSUCHCHANNEL + | ERR_CANNOTSENDTOCHAN + | ERR_TOOMANYCHANNELS + | ERR_WASNOSUCHNICK + | ERR_TOOMANYTARGETS + | ERR_NOSUCHSERVICE + | ERR_NOORIGIN + | ERR_NORECIPIENT + | ERR_NOTEXTTOSEND + | ERR_NOTOPLEVEL + | ERR_WILDTOPLEVEL + | ERR_BADMASK + | ERR_UNKNOWNCOMMAND + | ERR_NOMOTD + | ERR_NOADMININFO + | ERR_FILEERROR + | ERR_NONICKNAMEGIVEN + | ERR_ERRONEUSNICKNAME + | ERR_NICKNAMEINUSE + | ERR_NICKCOLLISION + | ERR_UNAVAILRESOURCE + | ERR_USERNOTINCHANNEL + | ERR_NOTONCHANNEL + | ERR_USERONCHANNEL + | ERR_NOLOGIN + | ERR_SUMMONDISABLED + | ERR_USERSDISABLED + | ERR_NOTREGISTERED + | ERR_NEEDMOREPARAMS + | ERR_ALREADYREGISTRED + | ERR_NOPERMFORHOST + | ERR_PASSWDMISMATCH + | ERR_YOUREBANNEDCREEP + | ERR_YOUWILLBEBANNED + | ERR_KEYSET + | ERR_CHANNELISFULL + | ERR_UNKNOWNMODE + | ERR_INVITEONLYCHAN + | ERR_BANNEDFROMCHAN + | ERR_BADCHANNELKEY + | ERR_BADCHANMASK + | ERR_NOCHANMODES + | ERR_BANLISTFULL + | ERR_NOPRIVILEGES + | ERR_CHANOPRIVSNEEDED + | ERR_CANTKILLSERVER + | ERR_RESTRICTED + | ERR_UNIQOPPRIVSNEEDED + | ERR_NOOPERHOST + | ERR_UMODEUNKNOWNFLAG + | ERR_USERSDONTMATCH + deriving (Eq,Generic,Hashable,Show) + +instance ConvertibleStrings Text Command where + convertString = convert + where + convert s = M.lookupDefault (fallback s) s mTextCommand + fallback s = + case T.decimal s of + Right (i, "") -> UnknownReply i + _ -> UnknownCommand s + +instance ConvertibleStrings Command Text where + convertString = convert + where + convert c = M.lookupDefault (fallback c) c mCommandText + fallback = \case + UnknownCommand c -> c + UnknownReply i -> show3 i + x -> error ("no fallback for " <> show x) + +instance FromJSON Command where + parseJSON = \case + String t -> pure (convertString t) + invalid -> typeMismatch "Command" invalid + +instance FromJSONKey Command where + fromJSONKey = FromJSONKeyText convertString + + +commands :: [(Text, Command)] +commands = + [ ("ADMIN", ADMIN) + , ("AWAY", AWAY) + , ("CONNECT", CONNECT) + , ("DIE", DIE) + , ("ERROR", ERROR) + , ("INFO", INFO) + , ("INVITE", INVITE) + , ("ISON", ISON) + , ("JOIN", JOIN) + , ("KICK", KICK) + , ("KILL", KILL) + , ("LINKS", LINKS) + , ("LIST", LIST) + , ("LUSERS", LUSERS) + , ("MODE", MODE) + , ("MOTD", MOTD) + , ("NAMES", NAMES) + , ("NICK", NICK) + , ("NJOIN", NJOIN) + , ("NOTICE", NOTICE) + , ("OPER", OPER) + , ("PART", PART) + , ("PASS", PASS) + , ("PING", PING) + , ("PONG", PONG) + , ("PRIVMSG", PRIVMSG) + , ("QUIT", QUIT) + , ("REHASH", REHASH) + , ("RESTART", RESTART) + , ("SERVER", SERVER) + , ("SERVICE", SERVICE) + , ("SERVLIST", SERVLIST) + , ("SQUERY", SQUERY) + , ("SQUIRT", SQUIRT) + , ("SQUIT", SQUIT) + , ("STATS", STATS) + , ("SUMMON", SUMMON) + , ("TIME", TIME) + , ("TOPIC", TOPIC) + , ("TRACE", TRACE) + , ("USER", USER) + , ("USERHOST", USERHOST) + , ("USERS", USERS) + , ("VERSION", VERSION) + , ("WALLOPS", WALLOPS) + , ("WHO", WHO) + , ("WHOIS", WHOIS) + , ("WHOWAS", WHOWAS) + ] + +replies :: [(Int, Command)] +replies = + [ (001, RPL_WELCOME) + , (002, RPL_YOURHOST) + , (003, RPL_CREATED) + , (004, RPL_MYINFO) + , (005, RPL_BOUNCE) + + , (200, RPL_TRACELINK) + , (201, RPL_TRACECONNECTING) + , (202, RPL_TRACEHANDSHAKE) + , (203, RPL_TRACEUNKNOWN) + , (204, RPL_TRACEOPERATOR) + , (205, RPL_TRACEUSER) + , (206, RPL_TRACESERVER) + , (207, RPL_TRACESERVICE) + , (208, RPL_TRACENEWTYPE) + , (209, RPL_TRACECLASS) + , (210, RPL_TRACERECONNECT) + , (211, RPL_STATSLINKINFO) + , (212, RPL_STATSCOMMANDS) + , (219, RPL_ENDOFSTATS) + , (221, RPL_UMODEIS) + , (234, RPL_SERVLIST) + , (235, RPL_SERVLISTEND) + , (242, RPL_STATSUPTIME) + , (243, RPL_STATSOLINE) + , (251, RPL_LUSERCLIENT) + , (252, RPL_LUSEROP) + , (253, RPL_LUSERUNKNOWN) + , (254, RPL_LUSERCHANNELS) + , (255, RPL_LUSERME) + , (256, RPL_ADMINME) + , (257, RPL_ADMINLOC1) + , (258, RPL_ADMINLOC2) + , (259, RPL_ADMINEMAIL) + , (261, RPL_TRACELOG) + , (262, RPL_TRACEEND) + , (263, RPL_TRYAGAIN) + , (301, RPL_AWAY) + , (302, RPL_USERHOST) + , (303, RPL_ISON) + , (305, RPL_UNAWAY) + , (306, RPL_NOWAWAY) + , (311, RPL_WHOISUSER) + , (312, RPL_WHOISSERVER) + , (313, RPL_WHOISOPERATOR) + , (314, RPL_WHOWASUSER) + , (315, RPL_ENDOFWHO) + , (317, RPL_WHOISIDLE) + , (318, RPL_ENDOFWHOIS) + , (319, RPL_WHOISCHANNELS) + , (321, RPL_LISTSTART) + , (322, RPL_LIST) + , (323, RPL_LISTEND) + , (324, RPL_CHANNELMODEIS) + , (325, RPL_UNIQOPIS) + , (331, RPL_NOTOPIC) + , (332, RPL_TOPIC) + , (341, RPL_INVITING) + , (342, RPL_SUMMONING) + , (346, RPL_INVITELIST) + , (347, RPL_ENDOFINVITELIST) + , (348, RPL_EXCEPTLIST) + , (349, RPL_ENDOFEXCEPTLIST) + , (351, RPL_VERSION) + , (352, RPL_WHOREPLY) + , (353, RPL_NAMREPLY) + , (364, RPL_LINKS) + , (365, RPL_ENDOFLINKS) + , (366, RPL_ENDOFNAMES) + , (367, RPL_BANLIST) + , (368, RPL_ENDOFBANLIST) + , (369, RPL_ENDOFWHOWAS) + , (371, RPL_INFO) + , (372, RPL_MOTD) + , (374, RPL_ENDOFINFO) + , (375, RPL_MOTDSTART) + , (376, RPL_ENDOFMOTD) + , (381, RPL_YOUREOPER) + , (382, RPL_REHASHING) + , (383, RPL_YOURESERVICE) + , (391, RPL_TIME) + , (392, RPL_USERSSTART) + , (393, RPL_USERS) + , (394, RPL_ENDOFUSERS) + , (395, RPL_NOUSERS) + + , (401, ERR_NOSUCHNICK) + , (402, ERR_NOSUCHSERVER) + , (403, ERR_NOSUCHCHANNEL) + , (404, ERR_CANNOTSENDTOCHAN) + , (405, ERR_TOOMANYCHANNELS) + , (406, ERR_WASNOSUCHNICK) + , (407, ERR_TOOMANYTARGETS) + , (408, ERR_NOSUCHSERVICE) + , (409, ERR_NOORIGIN) + , (411, ERR_NORECIPIENT) + , (412, ERR_NOTEXTTOSEND) + , (413, ERR_NOTOPLEVEL) + , (414, ERR_WILDTOPLEVEL) + , (415, ERR_BADMASK) + , (421, ERR_UNKNOWNCOMMAND) + , (422, ERR_NOMOTD) + , (423, ERR_NOADMININFO) + , (424, ERR_FILEERROR) + , (431, ERR_NONICKNAMEGIVEN) + , (432, ERR_ERRONEUSNICKNAME) + , (433, ERR_NICKNAMEINUSE) + , (436, ERR_NICKCOLLISION) + , (437, ERR_UNAVAILRESOURCE) + , (441, ERR_USERNOTINCHANNEL) + , (442, ERR_NOTONCHANNEL) + , (443, ERR_USERONCHANNEL) + , (444, ERR_NOLOGIN) + , (445, ERR_SUMMONDISABLED) + , (446, ERR_USERSDISABLED) + , (451, ERR_NOTREGISTERED) + , (461, ERR_NEEDMOREPARAMS) + , (462, ERR_ALREADYREGISTRED) + , (463, ERR_NOPERMFORHOST) + , (464, ERR_PASSWDMISMATCH) + , (465, ERR_YOUREBANNEDCREEP) + , (466, ERR_YOUWILLBEBANNED) + , (467, ERR_KEYSET) + , (471, ERR_CHANNELISFULL) + , (472, ERR_UNKNOWNMODE) + , (473, ERR_INVITEONLYCHAN) + , (474, ERR_BANNEDFROMCHAN) + , (475, ERR_BADCHANNELKEY) + , (476, ERR_BADCHANMASK) + , (477, ERR_NOCHANMODES) + , (478, ERR_BANLISTFULL) + , (481, ERR_NOPRIVILEGES) + , (482, ERR_CHANOPRIVSNEEDED) + , (483, ERR_CANTKILLSERVER) + , (484, ERR_RESTRICTED) + , (485, ERR_UNIQOPPRIVSNEEDED) + , (491, ERR_NOOPERHOST) + , (501, ERR_UMODEUNKNOWNFLAG) + , (502, ERR_USERSDONTMATCH) + ] + +mCommandText :: HashMap Command Text +mCommandText = + M.fromList $ + map (\(s,c) -> (c,s)) commands <> + map (\(i,c) -> (c,show3 i)) replies + +mTextCommand :: HashMap Text Command +mTextCommand = + M.fromList $ + map (\(s,c) -> (s,c)) commands <> + map (\(i,c) -> (show3 i,c)) replies + +show3 :: Int -> Text +show3 i = + p <> s + where s = T.show i + p = T.replicate (3 - T.length s) "0" |