diff options
| author | pb <pb@9f8f72e9-4bf4-416e-b76e-7d4203597157> | 2010-03-28 10:42:32 +0000 |
|---|---|---|
| committer | pb <pb@9f8f72e9-4bf4-416e-b76e-7d4203597157> | 2010-03-28 10:42:32 +0000 |
| commit | 3911a1935535df6d65694339e7f7140714379b56 (patch) | |
| tree | 2f558d279e8ded4f35ea2de7016323845615f252 /HsBot/IRC.hs | |
| parent | 561aa6d45ed2c7dc6cd177bab5c31f6d8fccde66 (diff) | |
git-svn-id: https://ssl.buetow.org/repos/hsbot/trunk@45 9f8f72e9-4bf4-416e-b76e-7d4203597157
Diffstat (limited to 'HsBot/IRC.hs')
| -rw-r--r-- | HsBot/IRC.hs | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/HsBot/IRC.hs b/HsBot/IRC.hs new file mode 100644 index 0000000..28fc9f0 --- /dev/null +++ b/HsBot/IRC.hs @@ -0,0 +1,96 @@ +module HsBot.IRC (ircStart) where + +import IO +import List +import Network +import System +import System.IO +import Text.Printf + +import HsBot.Conf +import HsBot.Env +import HsBot.State +import HsBot.Tools +import HsBot.User + +data IrcMessage = IrcMessage { + raw :: String, + from :: String, + clean :: String, + isQuery :: Bool + } deriving Show + +ircWrite :: Handle -> String -> String -> IO () +ircWrite h s t = do + printf "> %s %s\n" s t + hPrintf h "%s %s\r\n" s t + +ircPrivMsg :: Handle -> IrcMessage -> Env -> String -> IO () +ircPrivMsg h msg env@(Env state _) s = do + ircPrivMsg' $ if isMultiline s then (lines s) else [s] + where + ircPrivMsg' [] = return () + ircPrivMsg' (x:xs) = + let maxMessageSize = + envGetInt "maxMessageSize" env + receiver = + if (isQuery msg) + then from msg + else currentChannel state + in if length x > maxMessageSize + then do + ircWrite h "PRIVMSG" (receiver ++ " :" + ++ (take maxMessageSize x) ++ "...") + ircWrite h "PRIVMSG" (receiver ++ " :" + ++ "...this message has been cut to " + ++ (show maxMessageSize) ++ " chars") + ircPrivMsg' xs + else do + ircWrite h "PRIVMSG" (receiver ++ " :" ++ x) + ircPrivMsg' xs + +ircStart :: Env -> IO () +ircStart (DispatchEnv state conf dispatch) = do + ircChannel <- get "ircChannel" conf + ircNick <- get "ircNick" conf + ircPort <- get "ircPort" conf + ircServer <- get "ircServer" conf + ircUser <- get "ircUser" conf + h <- connectTo ircServer (PortNumber $ fromIntegral (read ircPort :: Int)) + hSetBuffering h NoBuffering + ircWrite h "NICK" ircNick + ircWrite h "USER" $ ircNick ++ " 0 * :" ++ ircUser + ircEvalLoop h (DispatchEnv state { currentChannel = ircChannel } conf dispatch) + return () + +ircEvalLoop :: Handle -> Env -> IO () +ircEvalLoop h env = do + t <- hGetLine h + let s = init t + env' <- branch s + ircEvalLoop h env' + where + branch s + | ping s = do { pong s; return (env) } + | otherwise = ircEval h (msg s) env + ping x = "PING :" `isPrefixOf` x + pong x = ircWrite h "PONG" (':' : drop 6 x) + from = drop 1 . takeWhile (/= '!') + clean = drop 1 . dropWhile (/= ':') . drop 1 + isQuery x = split x ' ' !! 2 == (envGet "ircNick" env) + msg s = IrcMessage { + raw = s, from = from s, + clean = clean s, isQuery = isQuery s + } + +ircEval :: Handle -> IrcMessage -> Env -> IO Env +ircEval h msg env@(DispatchEnv state _ dispatch) = ircEval' (clean msg) + where + ircEval' "+x" = do + ircWrite h "JOIN" (currentChannel state) + return (env) + ircEval' cleanMsg = do + (Env s c) <- dispatch cleanMsg sendReplyMsg (castEnv env) + return (DispatchEnv s c dispatch) + sendReplyMsg = ircPrivMsg h msg (castEnv env) + |
