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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
module Hsbot.Types
( AccessList (..)
, AccessRight (..)
, Bot
, BotState (..)
, BotStatus (..)
, BotEnv (..)
, Config (..)
, Env
, Message (..)
, Plugin
, PluginEnv (..)
, PluginId (..)
, TLSConfig (..)
) where
import Control.Concurrent
import qualified Data.Map as M
import Control.Monad.Reader
import Control.Monad.State
import Network
import qualified Network.IRC as IRC
import Network.TLS
import System.IO
-- The bot environment
type Env = ReaderT BotEnv
data BotEnv = BotEnv
{ envBotState :: MVar BotState
, envHandle :: Handle
, envChan :: Chan Message
, envQuitMv :: MVar BotStatus
, envThreadIdsMv :: MVar [ThreadId]
, envConfig :: Config
, envTLS :: Maybe TLSParams
, envTLSCtx :: Maybe (TLSCtx Handle)
}
-- The bot monad
type Bot = StateT BotState
data BotState = BotState
{ botPlugins :: M.Map String (PluginEnv, ThreadId)
, botAccess :: [AccessList]
, botHooks :: [Chan Message]
, botChannels :: [String]
, botNickname :: String
}
-- The Plugin monad
type Plugin = ReaderT PluginEnv
data PluginEnv = PluginEnv
{ pluginId :: PluginId
, pluginChan :: Chan Message
, pluginMaster :: Chan Message
}
data PluginId = PluginId
{ pluginName :: String
, pluginEp :: Plugin (Env IO) ()
}
-- Messaging
data Message = IncomingMsg IRC.Message
| OutgoingMsg IRC.Message
data BotStatus = BotExit | BotReload String | BotRestart (String, Maybe String) deriving (Read, Show)
-- Config
data Config = Config
{ configErrors :: Maybe String
, configTLS :: TLSConfig
, configAddress :: String
, configPort :: PortID
, configPassword :: Maybe String
, configAccess :: [AccessList]
, configChannels :: [String]
, configNicknames :: [String]
, configRealname :: String
, configPlugins :: [PluginId]
}
data AccessRight = Admin | JoinPart | Kick | Say deriving (Eq, Show)
data AccessList = AccessList
{ accessMask :: IRC.Prefix
, accessList :: [AccessRight]
} deriving (Show)
data TLSConfig = TLSConfig
{ sslOn :: Bool
, sslVersions :: [Network.TLS.Version]
, sslCiphers :: [Network.TLS.Cipher]
, sslVerify :: Bool
, sslLogging :: TLSLogging
}
|