root/trunk/Phergie/Plugin/Math.php @ 60

Revision 60, 3.8 KB (checked in by tobias382, 5 years ago)

Fixes #1, #8, #14, #10, #13
* Fixed some parameter parsing issues in the streams driver and Command plugin
* Fixed an issue in the streams driver where quitting would not cause the

connection to be terminated on the client side

* Added automated directory creation to the event handler class
* Added isInChannel() and TYPE_KICK to request event class
* Modified the bootstrap file to use a full path when referencing the Plugin

directory and to include plugin loading debugging messages

* Fixed a bug in the bootstrap file where it would not produce an error when

required configuration settings existed, but were empty

* Cleared default values and unused settings out of the config file
* Made modifications to the fromAdmin method in the AdminCommand? plugin to

optimize performance

* Fixed a bug in the parsing logic in the Acronym plugin and added a check for

instances where the per-IP bandwidth limit has been executed

* Added a check for cases where a server has no MOTD to the Autojoin plugin
* Modified the Drink plugin to filter coffee drinks when scraping data for the

coke table and to remove the profanity filter array from memory once the
init method is done using it

* Added an avogadro alias for the mole fixed karma and added support for

configurable fixed karma for the bot

* Modified the Logging plugin to extend the Command plugin and to use PDO in

place of the standalone SQLite driver

* Modified the Php plugin to use full URLs to function pages rather than the

shorthand version, which does not always resolve to the expected URL

* Renamed the Say plugin to Puppet and added support emulation of CTCP ACTION

commands

* Modified the Url plugin to use the MIME type of the resource in place of

the title in cases where it is not HTML-based

* Fixed an issue with the parsing logic in the onMode handler of the Users

plugin

* Uncommented the onPrivmsg handler and modified it to use the new debug

configuration setting

* Added alternate nick support to the Nickserv plugin
* Removed the CONTRIBUTE file, as its fairly out of date

Line 
1<?php
2
3/**
4* @see Phergie_Event_Handler
5*/
6require_once 'Phergie/Event/Handler.php';
7
8/**
9* Checks incoming requests for simple mathematical expressions, computes the
10* result of such expressions, and responds with a message containing the
11* result.
12*/
13class Phergie_Plugin_Math extends Phergie_Event_Handler
14{
15    /**
16    * Holds the allowed function, characters, operators and constants
17    *
18    * @var array
19    */
20    protected $allowed = array
21    (
22        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
23        '+', '-', '/', '*', '.', ' ', '<<', '>>', '%', '&', '^', '|', '~',
24        'abs(', 'ceil(', 'floor(', 'exp(',
25        'log10(',
26        'cos(', 'sin(', 'sqrt(', 'tan(',
27        'M_PI', 'INF', 'M_E',
28    );
29
30    /**
31    * Holds the functions that can accept multiple arguments.
32    *
33    * @return void
34    */
35    protected $funcs = array
36    (
37        'round(', 'log(', 'pow(',
38        'max(', 'min(', 'rand(',
39    );
40
41    /**
42    * Parses a simple arithmetic expression, evaluates it, and returns the
43    * result to the sender.
44    *
45    * @return void
46    */
47    public function onPrivmsg()
48    {
49        $source = $this->event->getSource();
50        $message = $this->event->getArgument(1);
51        if (preg_match('/^(?:math|calc) /', $message)) {
52            // Get equation
53            $equation = substr($message, 5);
54            // Replace constants
55            $equation = str_ireplace(
56                array('pi', 'M_PI()', 'chucknorris', 'inf', ' e '),
57                array('M_PI', 'M_PI', 1e10000, 'INF', ' M_E '),
58                $equation
59            );
60            $equationSrc = $equation;
61
62            // Parse equation
63            $out = '';
64            $ptr = 1;
65            $allowcomma = 0;
66            while (strlen($equation) > 0) {
67                $substr = substr($equation, 0, $ptr);
68                // Allowed string
69                if (array_search($substr, $this->allowed) !== false) {
70                    $out .= $substr;
71                    $equation = substr($equation, $ptr);
72                    $ptr = 0;
73                // Allowed func
74                } elseif (array_search($substr, $this->funcs) !== false) {
75                    $out .= $substr;
76                    $equation = substr($equation, $ptr);
77                    $ptr = 0;
78                    $allowcomma++;
79                    if ($allowcomma === 1) {
80                        $this->allowed[] = ',';
81                    }
82                // Opening parenthesis
83                } elseif ($substr === '(') {
84                    if ($allowcomma > 0) {
85                        $allowcomma++;
86                    }
87                    $out .= $substr;
88                    $equation = substr($equation, $ptr);
89                    $ptr = 0;
90                // Closing parenthesis
91                } elseif ($substr === ')') {
92                    if ($allowcomma > 0) {
93                        $allowcomma--;
94                        if($allowcomma === 0) {
95                            array_pop($this->allowed);
96                        }
97                    }
98
99                    $out .= $substr;
100                    $equation = substr($equation, $ptr);
101                    $ptr = 0;
102                // Parse error if we've consumed the entire equation without finding anything valid
103                } elseif ($ptr >= strlen($equation)) {
104                    $this->doPrivmsg($source, 'Syntax error at "' . $substr . '" in equation "' . $equationSrc . '"');
105                    return;
106                } else {
107                    $ptr++;
108                }
109            }
110            $res = @eval('return ' . $out . ';');
111            if($res === false) {
112                $this->doPrivmsg($source, 'Computation error, division by zero?');
113            } else {
114                $this->doPrivmsg($source, $res);
115            }
116        }
117    }
118}
Note: See TracBrowser for help on using the browser.