summaryrefslogtreecommitdiff
path: root/HsBot/IRC.hs
diff options
context:
space:
mode:
authorpb <pb@9f8f72e9-4bf4-416e-b76e-7d4203597157>2010-03-28 11:04:15 +0000
committerpb <pb@9f8f72e9-4bf4-416e-b76e-7d4203597157>2010-03-28 11:04:15 +0000
commit7a7302c5b86e89f3fc2fbc3476db731dfd6ed11b (patch)
treec0b5c50229b9f5a08833ec2e589a5b13a943b516 /HsBot/IRC.hs
parent6f5773590d2a1453aba3c47bcca286c4ffeb93bd (diff)
git-svn-id: https://ssl.buetow.org/repos/hsbot/trunk@49 9f8f72e9-4bf4-416e-b76e-7d4203597157
Diffstat (limited to 'HsBot/IRC.hs')
-rw-r--r--HsBot/IRC.hs96
1 files changed, 96 insertions, 0 deletions
diff --git a/HsBot/IRC.hs b/HsBot/IRC.hs
new file mode 100644
index 0000000..7efb732
--- /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.General.Tools
+import HsBot.IRC.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)
+