diff options
-rw-r--r-- | hirc.hs | 45 |
1 files changed, 32 insertions, 13 deletions
@@ -1,4 +1,5 @@ {-# LANGUAGE LambdaCase #-} +{-# LANGUAGE RecordWildCards #-} import Data.List import Data.Monoid import Network @@ -13,30 +14,42 @@ import Hirc.Types import Text.Parsec (parse) import Text.Printf -server = "irc.freenode.org" -port = 6667 -chan = "#hirc-testing" -nick = "hirc" - -filename = server <> (':' : show port) +data Config = + Config { + server :: String, + port :: Int, + chan :: String, + nick :: String + } + deriving Show -- The 'Net' monad, a wrapper over IO, carrying the bot's immutable state. type Net = ReaderT Bot IO -data Bot = Bot { socket :: Handle } +data Bot = Bot { + config :: Config, + socket :: Handle +} -- Set up actions to run on start and end, and run the main loop main :: IO () -main = bracket connect disconnect loop +main = bracket (connect c) disconnect loop where disconnect = hClose . socket loop st = runReaderT run st + c = Config { + server = "irc.freenode.org", + port = 6667, + chan = "#hirc-testing", + nick = "hirc" + } + -- Connect to the server and return the initial bot state -connect :: IO Bot -connect = notify $ do +connect :: Config -> IO Bot +connect c@Config{..} = notify $ do h <- connectTo server (PortNumber (fromIntegral port)) hSetBuffering h NoBuffering - return (Bot h) + return (Bot c h) where notify a = bracket_ (printf "Connecting to %s ... " server >> hFlush stdout) @@ -47,6 +60,7 @@ connect = notify $ do -- Join a channel, and start processing commands run :: Net () run = do + Config{..} <- asks config write "NICK" nick write "USER" (nick++" 0 * :hirc bot") asks socket >>= listen @@ -54,6 +68,8 @@ run = do -- Process each line from the server listen :: Handle -> Net () listen h = forever $ do + c@Config{..} <- asks config + let filename = server <> (':' : show port) s <- init `fmap` io (hGetLine h) io (putStrLn s) case parse P.message filename s of @@ -65,7 +81,8 @@ eval :: Message -> Net () eval = \case Message _ "PING" [x] -> write "PONG" (':' : x) - Message _ "376" _ -> -- End of /MOTD command. + Message _ "376" _ -> do -- End of /MOTD command. + Config{..} <- asks config write "JOIN" chan Message _ "PRIVMSG" [chan, "!quit"] -> do write "QUIT" ":Exiting" @@ -78,7 +95,9 @@ eval = \case -- Send a privmsg to the current chan + server privmsg :: String -> Net () -privmsg s = write "PRIVMSG" (chan ++ " :" ++ s) +privmsg s = do + Config{..} <- asks config + write "PRIVMSG" (chan ++ " :" ++ s) -- Send a message out to the server we're currently connected to write :: String -> String -> Net () |