Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /**
- * Module: RandomQuote
- *
- * This module provides functionality for some randomness. That description
- * might be random, but that's precisely the purpose of this module; being
- * random. Basically, what it does is monitoring a channel and storing the last
- * x messages in that channel (x can get configured). Then, after a random time
- * interval, the Timer gets called and one of those messages is repeated in the
- * channel. This can result in funny situations, which might liven up a dead
- * channel.
- *
- * This module is completely configuration-less, so just plug it into your bot
- * and start spamming channels, but be sure to ask for the channel founder's
- * permission. I'm not responsible for your bot getting banned for annoying
- * behaviour.
- *
- * @author Mr. Bondt <mrbondt@goldenak.eu>
- */
- class RandomQuote extends ModuleBase
- {
- /**
- * Array of channels where this module will be activated in.
- */
- private $m_aChannels;
- /**
- * This array contains the timestamp of the last message in every
- * channel.
- */
- private $m_aLastMessage;
- /**
- * This is timestamp of the last time the timer has run.
- */
- private $m_nLastRun;
- /**
- * Associative array with the last 100 messages of every channel this
- * module is active in.
- */
- private $m_aMessages;
- /**
- * The timer ID of the current active timer, if there is one.
- */
- private $m_sTimerId;
- /**
- * The number of messages we should store for each enabled channel.
- */
- private $m_nMessages;
- /**
- * The prefix for the Evaluation module. We save this here so we can
- * ignore message beginning with this.
- */
- private $m_sEvalPrefix;
- /**
- * This array will define if there's actually being talked in the channel.
- */
- private $m_aTalkInfo;
- /**
- * The constructor readies the module for use.
- */
- public function __construct ()
- {
- if (!is_dir ('Data/RandomQuote'))
- {
- mkdir ('Data/RandomQuote');
- }
- $aConf = Configuration :: getInstance () -> get ('Owners');
- $this -> m_sEvalPrefix = $aConf ['Prefix'];
- $this -> m_aTalkInfo = array ();
- $this -> setNumMessages (100);
- $this -> load ();
- // Set up timer.
- $this -> setupTimer ();
- }
- /**
- * The destructor saves the until saved messages to file.
- */
- public function __destruct ()
- {
- $this -> save ();
- }
- /**
- * Loads up the channels where this module should be activated in.
- */
- public function load ()
- {
- // Convert the old format to the new format, assume the first
- // configured network.
- $aNetworks = array_keys (Configuration :: getInstance () -> get ('Networks'));
- $sDefaultNetwork = $aNetworks [0];
- $this -> m_aChannels = array ();
- if (file_exists ('Data/RandomQuote/Channels.dat'))
- {
- $this -> m_aChannels = unserialize (file_get_contents ('Data/RandomQuote/Channels.dat'));
- }
- foreach ($this -> m_aChannels as $iIndex => $sChannel)
- {
- if (strpos ($sChannel, ':') !== false)
- {
- list ($sNetwork, $sChannel) = explode (':', $sChannel);
- }
- else
- {
- // Backward compatibility.
- $sNetwork = $sDefaultNetwork;
- if (file_exists ('Data/RandomQuote/Messages_' . $sChannel . '.txt'))
- {
- // Rename it
- rename (
- 'Data/RandomQuote/Messages_' . $sChannel . '.txt',
- 'Data/RandomQuote/Messages_' . $sNetwork . ',' . $sChannel . '.txt'
- );
- }
- $this -> m_aChannels [$iIndex] = $sNetwork . ':' . $sChannel;
- }
- $sFilename = 'Data/RandomQuote/Messages_' . $sNetwork . ',' . $sChannel . '.txt';
- if (file_exists ($sFilename))
- {
- $this -> m_aMessages [$sNetwork][$sChannel] = file ($sFilename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
- }
- }
- $tsTime = time ();
- foreach ($this -> m_aChannels as $sChannel)
- {
- $this -> m_aLastMessage [$sChannel] = $tsTime;
- // This should be fine now, as it's fixed in the previous loop.
- list ($sNetwork, $sChannel) = explode (':', $sChannel);
- if (!isset ($this -> m_aMessages [$sNetwork]))
- {
- $this -> m_aMessages [$sNetwork] = array ();
- }
- if (!isset ($this -> m_aMessages [$sNetwork][$sChannel]))
- {
- $this -> m_aMessages [$sNetwork][$sChannel] = array ();
- }
- }
- // Save any corrections made.
- $this -> save ();
- // Prevents spamming in a channel after just starting.
- $this -> m_nLastRun = $tsTime;
- }
- /**
- * Saves the channels where this module should be used.
- */
- public function save ()
- {
- file_put_contents ('Data/RandomQuote/Channels.dat', serialize ($this -> m_aChannels));
- foreach ($this -> m_aChannels as $sChannel)
- {
- list ($sNetwork, $sChannel) = explode (':', $sChannel);
- file_put_contents (
- 'Data/RandomQuote/Messages_' . $sNetwork . ',' . $sChannel . '.txt',
- implode (PHP_EOL, $this -> m_aMessages [$sNetwork][$sChannel])
- );
- }
- }
- /**
- * Returns the number of messages we're storing to use in random
- * messages.
- *
- * @return integer
- */
- public function getNumMessages ()
- {
- return $this -> m_nMessages;
- }
- /**
- * This method sets the number of messages we're storing for each
- * channel, which can be used to spam a random quote once in a while.
- *
- * @param integer $nMessages The number of messages to store.
- */
- public function setNumMessages ($nMessages)
- {
- $this -> m_nMessages = $nMessages;
- }
- /**
- * Enables this module for the given channel.
- *
- * @param string $sNetwork The network on which this channel resides.
- * @param string $sChannel The channel to add.
- * @return boolean
- */
- public function addChannel ($sNetwork, $sChannel)
- {
- $sChannel = strtolower ($sChannel);
- if ($this -> isChannelAdded ($sNetwork, $sChannel))
- {
- return false;
- }
- $this -> m_aChannels [] = $sNetwork . ':' . $sChannel;
- $this -> m_aMessages [$sNetwork][$sChannel] = array ();
- $this -> m_aLastMessage [$sNetwork . ':' . $sChannel] = 0;
- $this -> save ();
- return true;
- }
- /**
- * Disables this module for the given channel. If $bDelMessages is true
- * (default), the stored messages for the given channel will be deleted.
- *
- * @param string $sNetwork The network on which this channel resides.
- * @param string $sChannel The channel to remove.
- * @param boolean $bDelMessages Whether to delete the stored messages.
- * @return boolean
- */
- public function removeChannel ($sNetwork, $sChannel, $bDelMessages = true)
- {
- $sChannel = strtolower ($sChannel);
- if (!$this -> isChannelAdded ($sNetwork, $sChannel))
- {
- return false;
- }
- $bDone = false;
- foreach ($this -> m_aChannels as $nIndex => $sListedChannel)
- {
- if ($sListedChannel == $sNetwork . ':' . $sChannel)
- {
- unset ($this -> m_aChannels [$nIndex]);
- if ($bDelMessages)
- {
- unset ($this -> m_aMessages [$sNetwork][$sChannel]);
- }
- $bDone = true;
- break;
- }
- }
- $this -> save ();
- return $bDone;
- }
- /**
- * Checks whether this module is active in the given channel.
- *
- * @param string $sNetwork The network on which this channel resides.
- * @param string $sChannel The channel to check.
- * @return boolean
- */
- public function isChannelAdded ($sNetwork, $sChannel)
- {
- $sChannel = strtolower ($sChannel);
- return in_array ($sNetwork . ':' . $sChannel, $this -> m_aChannels);
- }
- /**
- * This method saves the message that has appeared in the given channel
- * for use as a possible random message. It'll also replace the bot's
- * own nickname with the nickname of the person who sent the message.
- *
- * @param string $sNetwork The network on which this channel resides.
- * @param string $sChannel The channel where the message appeared in.
- * @param string $sMessage The message itself.
- * @param string $sOwnNickname The bot's own nickname.
- */
- private function addMessage ($sNetwork, $sChannel, $sNickname, $sMessage, $sOwnNickname)
- {
- $sChannel = strtolower ($sChannel);
- if (!$this -> isChannelAdded ($sNetwork, $sChannel))
- {
- return;
- }
- if (strlen ($sMessage) > 1 && ($sMessage [0] == '!' || $sMessage [0] == '.'))
- {
- // It's a command, skip it. It may very well be (or is) a command of this bot.
- return;
- }
- if (substr ($sMessage, 0, strlen ($this -> m_sEvalPrefix)) == $this -> m_sEvalPrefix)
- {
- // This is meant for the Evaluation module, skip it.
- return;
- }
- // Replace bot's name with name of person who said it
- // First replace all caps bot's name with all caps person's name.
- $sMessage = str_replace (strtoupper ($sOwnNickname), strtoupper ($sNickname), $sMessage);
- // Also replace all lowercase, just to be perfect.
- $sMessage = str_replace (strtolower ($sOwnNickname), strtolower ($sNickname), $sMessage);
- // Not gonna bother with BrEeZeR talk.
- $sMessage = str_ireplace ($sOwnNickname, $sNickname, $sMessage);
- // We want unique messages in the buffer, but respond to non-unique messages as well.
- $this -> m_aLastMessage [$sNetwork . ':' . $sChannel] = time ();
- // Prevent adding the same messages (like when someone is spamming).
- // This is probably slow, but I don't care, since it works fine.
- if (in_array ($sMessage, $this -> m_aMessages [$sNetwork][$sChannel]))
- {
- return;
- }
- // Add the message to the beginning, so we can shave the old messages of.
- array_unshift ($this -> m_aMessages [$sNetwork][$sChannel], $sMessage);
- if (count ($this -> m_aMessages [$sNetwork][$sChannel]) > $this -> m_nMessages)
- {
- // Remove all messages above a certain index. This makes changes in the number of messages possible.
- for ($i = $this -> m_nMessages; $i < count ($this -> m_aMessages [$sNetwork][$sChannel]); $i ++)
- {
- unset ($this -> m_aMessages [$sNetwork][$sChannel][$i]);
- }
- }
- }
- /**
- * This method will setup the timer for the next random message. The
- * timer will always set up with a timeout between 7.5 and 15 minutes.
- */
- private function setupTimer ()
- {
- $this -> m_sTimerId = Timer :: Create
- (
- array ($this, 'runTimer'),
- mt_rand(450 , 900) * 1000,
- false
- );
- foreach ($this -> m_aTalked as $sChan => $bTalked)
- {
- $this -> m_aTalked [$sChan] = false;
- }
- }
- /**
- * This method will call the run() method and setup the timer for the
- * next round of randomness.
- */
- public function runTimer ()
- {
- $this -> save ();
- $this -> run ();
- $this -> setupTimer ();
- }
- /**
- * Spams every enabled channel with a random message.
- */
- public function run ()
- {
- $this -> save ();
- foreach ($this -> m_aChannels as $sChannel)
- {
- list ($sNetwork, $sChannel) = explode (':', $sChannel);
- // Have there been messages since the last time we spammed?
- if ($this -> m_aLastMessage [$sNetwork . ':' . $sChannel] < $this -> m_nLastRun)
- {
- continue;
- }
- // Do we have enough messages to be serious?
- if (count ($this -> m_aMessages [$sNetwork][$sChannel]) < 3)
- {
- continue;
- }
- $pBot = BotManager :: getInstance () -> offsetGet ('network:' . $sNetwork . ' channel:' . $sChannel);
- if ($pBot instanceof BotGroup)
- {
- if (count ($pBot) == 0)
- {
- // No bots found.
- echo 'Could not find a bot in ' . $sChannel . ' on ' . $sNetwork . PHP_EOL;
- continue;
- }
- else
- {
- $pBot = $pBot -> seek (0);
- }
- }
- // We start at index 2 because we don't want a repetition of one of the last messages.
- $nIndex = mt_rand (2, count ($this -> m_aMessages [$sNetwork][$sChannel]) - 1);
- $sMessage = $this -> m_aMessages [$sNetwork][$sChannel][$nIndex];
- if ($this -> m_aTalked [$sChannel])
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :' . $sMessage);
- // Call Pisg logging module, if it exists.
- if (class_exists ('Pisg'))
- {
- $pPisg = ModuleManager :: getInstance () -> offsetGet ('Pisg');
- if ($pPisg instanceof ModuleBase)
- {
- if (substr ($sMessage, 0, 8) == chr (1) . 'ACTION ')
- {
- $pPisg -> onCTCP ($pBot, $sChannel, $pBot ['Nickname'], 'ACTION', substr ($sMessage, 8, -1));
- }
- else
- {
- $pPisg -> onChannelPrivmsg ($pBot, $sChannel, $pBot ['Nickname'], $sMessage);
- }
- }
- }
- // Remove the message from the array, this prevents us from spammin' it again.
- unset ($this -> m_aMessages [$sNetwork][$sChannel][$nIndex]);
- // Make sure the indexes are following eachother up so that we can still use mt_rand ().
- $this -> m_aMessages [$sNetwork][$sChannel] = array_values ($this -> m_aMessages [$sNetwork][$sChannel]);
- }
- $this -> m_nLastRun = time ();
- }
- /**
- * Handles some basic commands for this module, but will mostly
- * be storing messages that occured in a channel which this module
- * is active in.
- *
- * @param Bot $pBot The bot which received the message.
- * @param string $sChannel The channel in which the message was received.
- * @param string $sNickname The nickname from whom we got the message.
- * @param string $sMessage The message itself.
- */
- public function onChannelPrivmsg (Bot $pBot, $sChannel, $sNickname, $sMessage)
- {
- // Is the channel active?
- if ($this -> isChannelAdded ($pBot ['Network'], $sChannel))
- {
- if (!isset ($this -> m_aTalked [$sChannel]))
- $this -> m_aTalked [$sChannel] = true;
- else
- $this -> m_aTalked [$sChannel] = true;
- }
- // Handle commands.
- list ($sTrigger, $sParams) = Util:: parseMessage ($sMessage);
- if ($sMessage [0] == '!')
- {
- switch ($sTrigger)
- {
- /**
- * Force an execution.
- */
- case '!runrandom':
- {
- $pEval = ModuleManager :: getInstance () -> offsetGet ('Evaluation');
- if (!$pEval -> checkSecurity ($pBot, 9999)) {
- // Not the (logged in) owner.
- return false;
- }
- $this -> run ();
- return;
- }
- /**
- * Add a new channel which we're expected to spam.
- */
- case '!addrandomchan':
- {
- $pEval = ModuleManager :: getInstance () -> offsetGet ('Evaluation');
- if (!$pEval -> checkSecurity ($pBot, 9999))
- {
- return false;
- }
- if ($sParams == null || substr ($sParams, 0, 1) != '#')
- {
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :10Usage: !addrandomchan Channel');
- }
- else
- {
- if ($this -> addChannel ($pBot ['Network'], $sParams))
- {
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :3Success: Channel ' . $sParams . ' added.');
- }
- else
- {
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :4Error: Channel ' . $sParams . ' is already added.');
- }
- }
- return;
- }
- /**
- * People might get tired of this too. But that's okay,
- * with this command one is able to remove the functionality.
- */
- case '!delrandomchan':
- case '!removerandomchan':
- {
- $pEval = ModuleManager :: getInstance () -> offsetGet ('Evaluation');
- if (!$pEval -> checkSecurity ($pBot, 9999))
- {
- return false;
- }
- if ($sParams == null || substr ($sParams, 0, 1) != '#')
- {
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :10Usage: !removerandomchan Channel');
- }
- else
- {
- if ($this -> removeChannel ($pBot ['Network'], $sParams))
- {
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :3Success: Channel ' . $sParams . ' removed.');
- }
- else
- {
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :4Error: Channel ' . $sParams . ' is not added.');
- }
- }
- return;
- }
- /**
- * Just want to pause the module? That's cool, use this command.
- * Note that new messages aren't stored.
- *
- * 22-11-2009: disabled since it just doesn't make sense without continuing to store messages.
- */
- /*case '!pauserandom':
- {
- $pEval = ModuleManager :: getInstance () -> offsetGet ('Evaluation');
- if (!$pEval -> checkSecurity ($pBot, 9999))
- {
- return false;
- }
- if ($sParams == null || substr ($sParams, 0, 1) != '#')
- {
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :10Usage: !pauserandom Channel');
- }
- else
- {
- if ($this -> removeChannel ($pBot ['Network'], $sParams, false))
- {
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :3Success: Channel ' . $sParams . ' stopped.');
- }
- else
- {
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :4Error: Channel ' . $sParams . ' is not added.');
- }
- }
- return;
- }*/
- /**
- * Get an overview of all the channels we're currently active in.
- */
- case '!listrandomchan':
- {
- $sMessage = '10* RandomQuote module active in (' . count ($this -> m_aChannels) . '): ';
- foreach ($this -> m_aChannels as $sListedChannel)
- {
- $sMessage .= $sListedChannel . ', ';
- }
- $pBot -> send ('PRIVMSG ' . $sChannel . ' :' . substr ($sMessage, 0, -2));
- return;
- }
- /**
- * Show some basic statistics.
- */
- case '!randomstats':
- {
- $sChannel = strtolower ($sChannel);
- if ($this -> isChannelAdded ($pBot ['Network'], $sChannel))
- {
- $pBot -> send
- (
- 'PRIVMSG ' . $sChannel . ' :10* Stats for ' . $sChannel . ': Number of messages: ' .
- count ($this -> m_aMessages [$pBot ['Network']][strtolower ($sChannel)]) .
- ' - Last message stored: ' . Util :: formatTime (time () - $this -> m_aLastMessage [$pBot ['Network'] . ':' . $sChannel], true) . ' ago'
- );
- }
- return;
- }
- }
- }
- if ($this -> isChannelAdded ($pBot ['Network'], $sChannel))
- {
- // Add the received message to the list.
- $this -> addMessage ($pBot ['Network'], $sChannel, $sNickname, $sMessage, $pBot ['Nickname']);
- }
- }
- /**
- * In order to catch the /me message as well, we're going to have to
- * parse the ACTION messages, because of a limitation in the Nuwani
- * framework. This will be done in this very method. The type ($sType)
- * we're looking for is ACTION.
- *
- * @param Bot $pBot The bot which received the message.
- * @param string $sChannel The channel in which the message was received.
- * @param string $sNickname The nickname from whom we got the message.
- * @param string $sType The CTCP type.
- * @param string $sMessage The message itself.
- */
- public function onCTCP (Bot $pBot, $sChannel, $sNickname, $sType, $sMessage)
- {
- if (strtoupper ($sType) == 'ACTION' && $this -> isChannelAdded ($pBot ['Network'], $sChannel))
- {
- $this -> addMessage ($pBot ['Network'], $sChannel, $sNickname, chr (1) . 'ACTION ' . $sMessage . chr (1), $pBot ['Nickname']);
- }
- }
- }
- ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement