By | fr33domlover |
At | 2016-01-24 |
Title | Implement private puppet mode logic |
Description |
Edit file src/Main.hs 33188 → 33188
60 60 , bsMemos = ms
61 61 , bsUserOptions = userOpts
62 62 , bsKnownNicks = nicks
63 63 , bsLastMsgTime = M.empty
64 64 , bsPuppet = M.empty
+ 65 , bsPrivPuppet = Nothing
65 66 }
66 67 67 68 -- | Event detector specification
68 69 matchers =
69 70 [ matchPrefixedCommand
… … … … Edit file src/FunBot/Puppet.hs 33188 → 33188
15 15 16 16 {-# LANGUAGE OverloadedStrings #-}
17 17 18 18 module FunBot.Puppet
19 19 ( puppetStart
+ 20 , puppetPrivateStart
20 21 , puppetEnd
+ 22 , puppetPrivateEnd
21 23 , puppetSay
+ 24 , puppetPrivateSay
22 25 )
23 26 where
24 27 25 28 import Formatting ((%))
26 29 import FunBot.Types
… … … … 50 53 let puppet' = M.insert chan nick puppet
51 54 modifyStateS $ \ s -> s { bsPuppet = puppet' }
52 55 return Nothing
53 56 else return $ Just True
54 57 + 58 -- | Start private puppet mode by the given nickname. Return 'Nothing' on
+ 59 -- success. Otherwise 'False' means private puppet mode is already on, and
+ 60 -- 'True' means it isn't but the user isn't a global puppeteer.
+ 61 puppetPrivateStart :: Nickname -> BotSession (Maybe Bool)
+ 62 puppetPrivateStart nick = do
+ 63 mpteer <- getStateS bsPrivPuppet
+ 64 if isJust mpteer
+ 65 then return $ Just False
+ 66 else do
+ 67 gpts <- getStateS $ stPuppeteers . bsSettings
+ 68 if nick `S.member` gpts
+ 69 then do
+ 70 modifyStateS $ \ s -> s { bsPrivPuppet = Just nick }
+ 71 return Nothing
+ 72 else return $ Just True
+ 73 55 74 -- | Stop puppet mode in a channel. Return 'Nothing' on success. Otherwise
56 75 -- 'False' means the channel isn't in puppet mode, and 'True' means it is, but
57 76 -- the user isn't a puppeteer there.
58 77 --
59 78 -- Note that any puppeteer can stop puppet mode, not necessarily the one who
… … … … 73 92 modifyStateS $ \ s -> s { bsPuppet = puppet' }
74 93 return Nothing
75 94 else return $ Just True
76 95 else return $ Just False
77 96 + 97 -- | Stop private puppet mode. Return 'Nothing' on success. Otherwise
+ 98 -- 'False' means private puppet mode is off, and 'True' means it's on, but
+ 99 -- the user isn't a global puppeteer.
+ 100 --
+ 101 -- Note that any global puppeteer can stop private puppet mode, not necessarily
+ 102 -- the one who started it. This can be useful in case the latter forgets to
+ 103 -- stop it or gets disconnected from IRC, and then someone else can do it.
+ 104 puppetPrivateEnd :: Nickname -> BotSession (Maybe Bool)
+ 105 puppetPrivateEnd nick = do
+ 106 mpteer <- getStateS bsPrivPuppet
+ 107 if isJust mpteer
+ 108 then do
+ 109 gpts <- getStateS $ stPuppeteers . bsSettings
+ 110 if nick `S.member` gpts
+ 111 then do
+ 112 modifyStateS $ \ s -> s { bsPrivPuppet = Nothing }
+ 113 return Nothing
+ 114 else return $ Just True
+ 115 else return $ Just False
+ 116 78 117 -- | While in puppet mode, ask the bot to send a message into the channel.
79 118 -- Return 'Nothing' on success (i.e. the message is sent to the IRC server).
80 119 -- Otherwise, 'False' means the channel isn't in puppet mode, and 'True' means
81 120 -- it is, but the user isn't the one who started it.
82 121 puppetSay
… … … … 94 133 then
95 134 let msg' =
96 135 if reveal
97 136 then formatMsg
98 137 ("[" % nickname % "] " % message)
+ 138 nick msg
+ 139 else msg
+ 140 in sendToChannel chan msg'
+ 141 else return $ Just True
+ 142 + 143 -- | While in private puppet mode, ask the bot to send a message to a user.
+ 144 -- Return 'Nothing' on success (i.e. the message is sent to the IRC server).
+ 145 -- Otherwise, 'False' means private puppet mode is off, and 'True' means
+ 146 -- it is, but the user isn't the one who started it.
+ 147 puppetPrivateSay
+ 148 :: Nickname -- ^ Recipient
+ 149 -> Nickname -- ^ Puppeteer
+ 150 -> MsgContent
+ 151 -> Bool -- ^ Whether to reveal the message comes from the puppeteer
+ 152 -> BotSession (Maybe Bool)
+ 153 puppetPrivateSay recip nick msg reveal = do
+ 154 mpteer <- getStateS bsPrivPuppet
+ 155 case mpteer of
+ 156 Nothing -> return $ Just False
+ 157 Just pteer ->
+ 158 if nick == pteer
+ 159 then
+ 160 let msg' =
+ 161 if reveal
+ 162 then formatMsg
+ 163 ("[" % nickname % "] " % message)
99 164 nick msg'
100 165 else msg
- 101 in sendToChannel chan msg'
+ 166 in sendToUser recip msg'
102 167 else return $ Just True
103 168 104 169 -- | Finish puppet mode in all channels. This can be useful for emergency etc.
105 170 -- Return whether succeeded, i.e. whether user is a global puppeteer.
106 171 puppetReset
107 172 :: Nickname -- ^ Must be a global puppeteer
- 108 -> Bool -- ^ Whether to announce end of puppet mode in channels
+ 173 -> Bool -- ^ Whether to announce end of puppet mode
109 174 -> BotSession Bool
110 175 puppetReset nick ann = do
111 176 gpteers <- getStateS $ stPuppeteers . bsSettings
112 177 if nick `S.member` gpteers
113 178 then do
114 179 puppetChans <- getStateS $ M.keys . bsPuppet
- 115 modifyStateS $ \ s -> s { bsPuppet = M.empty }
+ 180 muser <- getStateS bsPrivPuppet
+ 181 modifyStateS $
+ 182 \ s -> s { bsPuppet = M.empty, bsPrivPuppet = Nothing }
116 183 when ann $ do
- 117 let say chan =
- 118 sendToChannel chan $ MsgContent $
- 119 "Puppet mode reset by " <> unNickname nick
- 120 traverse_ say puppetChans
+ 184 let msg =
+ 185 MsgContent $ "Puppet mode reset by " <> unNickname nick
+ 186 traverse_ (flip sendToChannel msg) puppetChans
+ 187 traverse_ (flip sendToUser msg) muser
121 188 return True
122 189 else return False
… … … … Edit file src/FunBot/Types.hs 33188 → 33188
288 288 , bsKnownNicks :: HashMap Channel (HashSet Nickname)
289 289 -- | Time of last message per channel.
290 290 , bsLastMsgTime :: HashMap Channel UTCTime
291 291 -- | Channels for which puppet mode is enabled, and by which user.
292 292 , bsPuppet :: HashMap Channel Nickname
+ 293 -- | Whether private puppet mode is enabled, and by which user. It allows
+ 294 -- the user to ask the bot to send a private message to another user.
+ 295 , bsPrivPuppet :: Maybe Nickname
293 296 }
294 297 295 298 -- | Shortcut alias for bot session monad
296 299 type BotSession = Session BotEnv BotState
297 300 … … … …