I know Haskell fairly well, and I'm writing an IRC interface for my bot. I have the following problem:
After running the code..
module Main (main) where
import Network
import Data.List
import System.IO
server = "irc.freenode.org"
port = 6667
chan = "#tanuki"
nick = "DuckBot01"
main :: IO ()
main = do
bot <- connect
run bot
connect :: IO Handle
connect = notify $ do
h <- connectTo server (PortNumber (fromIntegral port))
hSetBuffering h NoBuffering
return $ Bot { socket = h }
where
notify a = do
putStrLn ("Connecting to " ++ server ++ " ... ") >> hFlush stdout
putStrLn "done."
a
run :: Handle -> IO ()
run h = do
write h "NICK" nick
write h "USER" (nick++" 0 * :tutorial bot")
write h "JOIN" chan
listen h
--
-- Process each line from the server
--
listen :: Handle -> IO ()
listen h = forever $ do
s <- init `fmap` hGetLine h
putStrLn s
if ping s then pong s else eval h (clean s)
where
forever a = a >> forever a
clean = drop 1 . dropWhile (/= ':') . drop 1
ping x = "PING :" `isPrefixOf` x
pong x = write h "PONG" (':' : drop 6 x)
eval :: Handle -> String -> IO ()
eval h "!quit" = write h "QUIT" ":byebye"
eval _ _ = return () -- ignore everything else
privmsg :: Handle -> String -> IO ()
privmsg h s = write h "PRIVMSG" (chan ++ " :" ++ s)
write :: Handle -> String -> String -> IO ()
write handle s t = do
hPrint handle $ s ++ " " ++ t ++ "\r\n"
putStrLn $ "> " ++ s ++ " " ++ t ++ "\n"
I get the following output in the terminal:
Loading package bytestring-0.9.2.1 ... linking ... done.
Loading package transformers-0.2.2.0 ... linking ... done.
Loading package mtl-2.0.1.0 ... linking ... done.
Loading package array-0.4.0.0 ... linking ... done.
Loading package deepseq-1.3.0.0 ... linking ... done.
Loading package text-0.11.1.13 ... linking ... done.
Loading package parsec-3.1.2 ... linking ... done.
Loading package unix-2.5.1.0 ... linking ... done.
Loading package network-2.3.0.10 ... linking ... done.
Connecting to irc.freenode.org ...
done.
> NICK DuckBot01
> USER DuckBot01 0 * :tutorial bot
> JOIN #tanuki
:cameron.freenode.net NOTICE * :*** Looking up your hostname...
:cameron.freenode.net NOTICE * :*** Checking Ident
:cameron.freenode.net NOTICE * :*** Found your hostname
:cameron.freenode.net NOTICE * :*** No Ident response
ERROR :Closing Link: 127.0.0.1 (Connection timed out)
*** Exception: <socket: 8>: hGetLine: end of file
Why does it time out? It's not my connection, my normal IRC client works fine. Help is appreciated.
Use hPutStr
instead of hPrint
so that way your \r\n
is rendered and sent to the server correctly. hPrint
will give you the same output as show
, which is not what you want. I recently made a bot following the Roll Your Own IRC Bot page, too, and I stuck with using hPrintf
.
hPutStrLn
automatically appends \n
to your string, so you don't need to put that in your write
if that's not what you want.
Also, you should change this bit.
return $ Bot { socket = h }
Your function is supposed to return a Handle
but you're returning a Bot
which you haven't defined. Just change it to return h
and you should be okay there. (Since you've got it to compile, I'm assuming you fixed that.)