summaryrefslogtreecommitdiff
path: root/Hsbot/Plugin.hs
blob: 13d0efcc3af9fe34d68e2bd556506e3c3bf7d0bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
module Hsbot.Plugin
    ( listPlugins
    , loadPlugin
    , sendToPlugin
    , unloadPlugin
    ) where

import Control.Concurrent
import Control.Concurrent.Chan()
import Control.Exception
import Control.Monad.State
import qualified Data.Map as M
import Data.Maybe()
import System.IO()

import Hsbot.Types
import Hsbot.Utils

-- | Loads a plugin into an ircBot
loadPlugin :: String -> (Chan BotMsg -> Chan BotMsg -> IO ()) -> IrcBot ()
loadPlugin name entryPoint = do
    bot <- get
    let oldPlugins = botPlugins bot
    plugin <- liftIO $ effectivelyLoadPlugin name entryPoint (botChannel bot)
    put $ bot { botPlugins = M.insert name plugin oldPlugins}

-- | Effectively try to load a plugin
effectivelyLoadPlugin :: String -> (Chan BotMsg -> Chan BotMsg -> IO ()) -> Chan BotMsg -> IO (Plugin)
effectivelyLoadPlugin name entryPoint serverChan = do
    putStrLn $ inColor ("Loaded (static) plugin: " ++ name) [32]
    chan <- newChan :: IO (Chan BotMsg)
    threadId <- forkIO $ entryPoint serverChan chan
    return $ Plugin name threadId chan

-- | Sends a list of loaded plugins
listPlugins :: IrcMsg -> String -> IrcBot ()
listPlugins originalRequest dest = do
    plugins <- gets botPlugins
    let listing = unwords $ M.keys plugins
    case M.lookup dest plugins of
        Just plugin -> sendToPlugin (InternalCmd $ IntCmd "ANSWER" "CORE" dest listing originalRequest) plugin
        Nothing     -> return ()

-- | Unloads a plugin
unloadPlugin :: String -> IrcBot ()
unloadPlugin name = do
    bot <- get
    let oldPlugins = botPlugins bot
    case M.lookup name oldPlugins of
        Just plugin -> do
            let newPlugins = M.delete name oldPlugins
            liftIO $ throwTo (pluginThreadId plugin) UserInterrupt
            put $ bot { botPlugins = newPlugins }
        Nothing     -> return ()

-- | Sends a msg to a plugin
sendToPlugin :: BotMsg -> Plugin -> IrcBot ()
sendToPlugin msg plugin = do
    let chan = pluginChannel plugin
    liftIO $ writeChan chan msg