123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- -- the comments are all outta wack too.
- --important, reminder, Digit ! This is stage4 type, not stage 3 type.
- -- therefor, mind your pastes from type 3 to type 4 need the " h" taken out of equations
- -- This is the Father Jack version of daskeb (digit's haskell bot).
- -- in this version
- -- its sole feature is to answer any question with:
- -- "Yes."
- -- or ...
- -- "That would be an ecumenical matter."
- import Data.List
- import Network
- import System.IO
- import System.Exit
- import Control.Arrow
- import Control.Monad.Reader
- import Control.Exception
- import Text.Printf
- import System.Random -- import random, it said, surely they meant import Random, trying System.Random
-
- --server = "irc.freenode.org"
- server = "irc.libera.chat"
- port = 6667
- --chan = "#fatherjack"
- --chan = "#ss-nsfw"
- --chan = "#systemcrafters"
- --chan = "#gentoo-weed"
- --chan = "#akashicwhatever"
- chan = "##?"
- --chan = "#cow"
- --chan = "#botwar"
- --chan = "#librespeech" -- :strontium.libera.chat 480 FatherJack #librespeech :Cannot join channel (+S) - SSL/TLS required
- --chan = "##spiritscience"
- --chan = "##philosophy" --blocked
- --chan = "##"
- ----------------------------chan = "#dbtfc"
- --chan = "#muhcows"
- --chan = "#twocows"
- nick = "FatherJack"
-
- -- The 'Net' monad, a wrapper over IO, carrying the bot's immutable state.
- type Net = ReaderT Bot IO
- data Bot = Bot { socket :: Handle }
-
- -- Set up actions to run on start and end, and run the main loop
- main :: IO ()
- main = bracket connect disconnect loop
- where
- disconnect = hClose . socket
- loop st = runReaderT run st
-
- -- Connect to the server and return the initial bot state
- connect :: IO Bot
- connect = notify $ do
- h <- connectTo server (PortNumber (fromIntegral port))
- hSetBuffering h NoBuffering
- return (Bot h)
- where
- notify a = bracket_
- (printf "Connecting to %s ... " server >> hFlush stdout)
- (putStrLn "done.")
- a
-
- -- We're in the Net monad now, so we've connected successfully
- -- Join a channel, and start processing commands
- run :: Net ()
- run = do
- write "NICK" nick
- write "USER" (nick++" 0 * :DigitsHaskellBot")
- write "JOIN" chan
- asks socket >>= listen
-
- -- Process each line from the server
- listen :: Handle -> Net ()
- listen h = forever $ do
- s <- init `fmap` io (hGetLine h)
- io (putStrLn s)
- if ping s then pong s else eval (clean s)
- where
- forever a = a >> forever a
- clean = drop 1 . dropWhile (/= ':') . drop 1
- ping x = "PING :" `isPrefixOf` x
- pong x = write "PONG" (':' : drop 6 x)
- ---- this is/was/willbe another way of doing it, with the randomised either answer.
- --let ecumenical = ["yes","that would be an ecumenical matter."]
- --let ecumenical = [("yes"),("that would be an ecumenical matter.")]
- --ecumenical = [("yes"),("that would be an ecumenical matter.")]
- -- oh oh array! lets try that!
- --ecumenical = array (1, 3) [(1, "yes"),(2, "that would be an ecumenical matter."),(3, "drink!")]
- -- Dispatch a command
- eval :: String -> Net ()
- ---- fatherjackbot:
- -- /THE/ FEATURE:
- ----iwishthisworkedsosomplesomethinglikesthis----eval x | "?" `isSuffixOf` x = privmsg (if "what""who""how""why""where""when" `isInfixOf` x then "that would be an ecumenical matter" else "yes")
- -- with a little help: https://stackoverflow.com/questions/56944717/how-can-i-make-the-target-of-a-conditional-be-any-of-many-search-for-any-of-a-l/56944826#56944826
- --interrogatives = ["what", "who", "how", "why", "where", "when"]
- --eval x | "?" `isSuffixOf` x = privmsg (if any (`isInfixOf` x) interrogatives then "that would be an ecumenical matter" else "yes")
- --
- --riddances = ["stfu", "shut up", "go away", "be quiet", "stop that", "enough", "!", "rage", "please stop", "Hush", "hush", "HUSH", "quiet you", "Quiet you", "QUIET", "please segfault", "segfault please", "fuckoff", "feckoff", "fuck off", "feck off", "fek off", "fekoff", "gtf", "please leave"] --standard
- riddances = ["stfu", "shut up", "go away", "be quiet", "stop that", "enough", "!!!", "rage", "please stop", "Hush", "hush", "HUSH", "quiet you", "Quiet you", "QUIET", "please segfault", "segfault please", "fuckoff", "feckoff", "fuck off", "feck off", "fek off", "fekoff", "gtf", "please leave"] --hardcore
- -----
- -------------
- ------------------------
- -----------------------------------
- --------------------------------------------------------------
- --interrogatives = ["what", "who", "how", "why", "where", "when", "which", " or ", "What", "Who", "How", "Why", "Where", "When", "Which", "Or ", "WHAT", "WHO", "HOW", "WHY", "WHERE", "WHEN", "WHICH", " OR "]
- interrogatives = ["wat", "what", "who", "how", "why", "where", "when", "which", " or ", "wtf", "What", "Who", "How", "Why", "Where", "When", "Which", "Or ", "WHAT", "WHO", "HOW", "WHY", "WHERE", "WHEN", "WHICH", " OR ", "WTF"]
- --
- -- suffix (use me, i worked fine!)
- eval x | "?" `isSuffixOf` x = privmsg (if any (`isInfixOf` x) interrogatives then "that would be an ecumenical matter" else "yes")
- --
- -- infix (testing) ... dangerously irritating, triggered by many urls.
- --eval x | "?" `isInfixOf` x = privmsg (if any (`isInfixOf` x) interrogatives then "that would be an ecumenical matter" else "yes")
- --
- --eval x | "?" `isSuffixOf` x = privmsg (if any (`isInfixOf` x) interrogatives then "that would be an ecumenical matter" else "yes")
- --
- ---------------------------------------------
- -------------------------------------------
- -----------------------------------
- ---------------------------
- -------------------
- -------------
- -----
- -- old prior scraps, kept here for elucidation of simpler forms
- --eval x | "?" `isSuffixOf` x = privmsg (if "FatherJackBot:" `isPrefixOf` x then "that would be an ecumenical matter" else "yes") -- well at least this one works.
- --eval x | "?" `isInfixOf` x = privmsg (if "FatherJackBot:" `isPrefixOf` x then "That would be an ecumenical matter." else "Yes.") -- well at least this one works.
- -- THE /ANTI/-FEATURE:
- eval x | "drink" `isInfixOf` x = privmsg (if "FatherJack:" `isPrefixOf` x then "glug glug glug" else "DRINK!")
- eval x | "Drink" `isInfixOf` x = privmsg (if "FatherJack:" `isPrefixOf` x then "glug glug glug" else "DRINK!")
- eval x | "drink" `isInfixOf` x = privmsg (if "gives FatherJack" `isInfixOf` x then "glug glug glug" else "DRINK!")
- eval x | "Drink" `isInfixOf` x = privmsg (if "givevs FatherJack" `isPrefixOf` x then "glug glug glug" else "DRINK!")
- -- ( THE OTHER /ANTI/-FEATURES: ) e.g.
- eval x | "Gerls!" `isInfixOf` x = privmsg (if "Fek!" `isInfixOf` x then "glug glug glug" else "DRINK!")
- -- but make these several arrays. gerls|Gerls|GERLS|girls|Girls|GIRLS etc and fek|Fek|FEK|feck|Feck|FECK etc etc.
- -- SAFETY DE-ANNOYANCE FEATURE
- --courtesy extra features: stfu & leave (/gtfo).
- -- the stfu feature is still in development
- -- current form, leaves if told to stfu directly.
- -- next intended dev goal: have gtfo > leave, and stfu > unresponsive mode
- -- (considering simply having gives drink be what makes fatherted go into stfu mode)
- -- (also considering having stfu include an optional timer, rather than toggle.)
- --eval x | "stfu" `isInfixOf` x = (if "FatherJackBot:" `isPrefixOf` x then write "QUIT" ":Exiting" >> io (exitWith ExitSuccess) else privmsg "hrm")
- --
- -- this version works great ----- or did i break it again, doh.
- --
- --eval x | "STFU!" `isInfixOf` x = (if "FatherJackBot:" `isPrefixOf` x then write "QUIT" ":Exiting" >> io (exitWith ExitSuccess) else return())
- --
- -- but i'm going to have a go putting in an aray like before.
- --
- --riddances = ["stfu", "shut up", "go away", "be quiet", "stop that", "enough", "!", "rage", "please stop"]
- --eval x | "!!!" `isInfixOf` x = privmsg (if any (`isInfixOf` x) riddances then write "QUIT" ":Exiting" >> io (exitWith ExitSuccess) else return())
- --desperate stab in the dark...
- --works but multiple declarations of eval... hrmmm
- eval x | "FatherJack" `isInfixOf` x = (if any (`isInfixOf` x) riddances then write "QUIT" ":Exiting" >> io (exitWith ExitSuccess) else return())
- --"that would be an ecumenical matter" else "yes")
- --
- -- TEMPORARY, For Morlog:
- eval ".seen wal" = privmsg ("no morlog, we've not seen em yet. keep looking.")
- --tbd: also, "i'm SO, SO sorry. :E :E :E" said before quitting...? it does take jack out of the well trained mode of that episode with the cardinals. twas sarcastic sorry to bishop brennan when he did that.
- --old basic leave, straight n clean, for reference:
- eval "!leave" = write "QUIT" ":Exiting" >> io (exitWith ExitSuccess)
- -- WEBSEARCH FEATURE
- eval x | "!search " `isPrefixOf` x = privmsg ("https://lmddgtfy.net/?q=" ++ (drop 8 x) ++ " ok?") -- added this back in to be useful.
- -- PARROT FEATURE
- eval x | "!repeat " `isPrefixOf` x = privmsg (drop 8 x) -- commented this out to minimise abuse
- eval _ = return () -- ignore everything else
-
- -- Send a privmsg to the current chan + server
- privmsg :: String -> Net ()
- privmsg s = write "PRIVMSG" (chan ++ " :" ++ s)
-
- -- Send a message out to the server we're currently connected to
- write :: String -> String -> Net ()
- write s t = do
- h <- asks socket
- io $ hPrintf h "%s %s\r\n" s t
- io $ printf "> %s %s\n" s t
-
- -- Convenience.
- io :: IO a -> Net a
- io = liftIO
|