| 1 | <?php |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | require_once 'Phergie/Plugin/Abstract/Base.php'; |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | class Phergie_Plugin_Karma extends Phergie_Plugin_Abstract_Base |
|---|
| 14 | { |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | protected $needsDir = true; |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | |
|---|
| 25 | |
|---|
| 26 | |
|---|
| 27 | protected $db = null; |
|---|
| 28 | |
|---|
| 29 | |
|---|
| 30 | |
|---|
| 31 | |
|---|
| 32 | |
|---|
| 33 | |
|---|
| 34 | protected $lastGc = null; |
|---|
| 35 | |
|---|
| 36 | |
|---|
| 37 | |
|---|
| 38 | |
|---|
| 39 | |
|---|
| 40 | |
|---|
| 41 | |
|---|
| 42 | protected $log = array(); |
|---|
| 43 | |
|---|
| 44 | |
|---|
| 45 | |
|---|
| 46 | |
|---|
| 47 | |
|---|
| 48 | |
|---|
| 49 | protected $fixedKarma; |
|---|
| 50 | |
|---|
| 51 | |
|---|
| 52 | |
|---|
| 53 | |
|---|
| 54 | protected $positiveAnswers; |
|---|
| 55 | |
|---|
| 56 | |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | protected $negativeAnswers; |
|---|
| 60 | |
|---|
| 61 | |
|---|
| 62 | |
|---|
| 63 | |
|---|
| 64 | |
|---|
| 65 | |
|---|
| 66 | protected $insertKarma; |
|---|
| 67 | protected $updateKarma; |
|---|
| 68 | protected $fetchKarma; |
|---|
| 69 | protected $insertComment; |
|---|
| 70 | |
|---|
| 71 | |
|---|
| 72 | |
|---|
| 73 | |
|---|
| 74 | |
|---|
| 75 | |
|---|
| 76 | |
|---|
| 77 | |
|---|
| 78 | public function init() |
|---|
| 79 | { |
|---|
| 80 | $this->db = null; |
|---|
| 81 | $this->lastGc = null; |
|---|
| 82 | $this->log = null; |
|---|
| 83 | |
|---|
| 84 | $this->fixedKarma = array |
|---|
| 85 | ( |
|---|
| 86 | 'phergie' => '%s has karma of awesome', |
|---|
| 87 | 'pi' => 'pi has karma of ' . M_PI, |
|---|
| 88 | 'chucknorris' => '%s has karma of Warning: Integer out of range', |
|---|
| 89 | 'chuck norris' => '%s has karma of Warning: Integer out of range', |
|---|
| 90 | 'c' => '%s has karma of 299 792 458 m/s', |
|---|
| 91 | 'e' => '%s has karma of ' . M_E, |
|---|
| 92 | 'euler' => '%s has karma of ' . M_EULER, |
|---|
| 93 | 'mole' => '%s has karma of 6.02214e23 molecules', |
|---|
| 94 | 'avogadro' => '%s has karma of 6.02214e23 molecules', |
|---|
| 95 | 'spoon' => '%s has no karma. There is no spoon', |
|---|
| 96 | 'mc^2' => '%s has karma of e', |
|---|
| 97 | 'mc2' => '%s has karma of e', |
|---|
| 98 | 'mc²' => '%s has karma of e', |
|---|
| 99 | 'i' => 'I haz big karma', |
|---|
| 100 | 'karma' => 'The karma law says that all living creatures are responsible for their karma - their actions and the effects of their actions. You should watch yours.', |
|---|
| 101 | 'answer to life, the universe, and everything' => 'The answer is 42', |
|---|
| 102 | 'the answer to life, the universe, and everything' => 'The answer is 42', |
|---|
| 103 | ); |
|---|
| 104 | |
|---|
| 105 | $this->positiveAnswers = array |
|---|
| 106 | ( |
|---|
| 107 | 'No kidding, %owner% totally kicks %owned%\'s ass !', |
|---|
| 108 | 'True that.', |
|---|
| 109 | 'I concur.', |
|---|
| 110 | 'Yay, %owner% ftw !', |
|---|
| 111 | '%owner% is made of WIN!', |
|---|
| 112 | 'Nothing can beat %owner%!', |
|---|
| 113 | ); |
|---|
| 114 | |
|---|
| 115 | $this->negativeAnswers = array |
|---|
| 116 | ( |
|---|
| 117 | 'No sir, not at all.', |
|---|
| 118 | 'You\'re wrong dude, %owner% wins.', |
|---|
| 119 | 'I\'d say %owner% is better than %owned%.', |
|---|
| 120 | 'You must be joking, %owner% ftw!', |
|---|
| 121 | '%owned% is made of LOSE!', |
|---|
| 122 | '%owned% = Epic Fail', |
|---|
| 123 | ); |
|---|
| 124 | |
|---|
| 125 | $static = $this->getPluginIni('static'); |
|---|
| 126 | if ($static) { |
|---|
| 127 | $this->fixedKarma[strtolower($this->getIni('nick'))] = $static; |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | |
|---|
| 131 | $db = $this->dir . 'karma.db'; |
|---|
| 132 | if (!file_exists($db)) { |
|---|
| 133 | $this->db = new PDO('sqlite:' . $db); |
|---|
| 134 | $this->db->query(' |
|---|
| 135 | CREATE TABLE karmas ( word VARCHAR ( 255 ) , karma MEDIUMINT ) ; |
|---|
| 136 | CREATE UNIQUE INDEX word ON karmas ( word ) ; |
|---|
| 137 | CREATE INDEX karmaIndex ON karmas ( karma ) ; |
|---|
| 138 | '); |
|---|
| 139 | $this->db->query(' |
|---|
| 140 | CREATE TABLE comments ( wordid INT , comment VARCHAR ( 255 ) ) ; |
|---|
| 141 | CREATE INDEX wordidIndex ON comments ( wordid ) ; |
|---|
| 142 | CREATE UNIQUE INDEX commentUnique ON comments ( comment ) ; |
|---|
| 143 | '); |
|---|
| 144 | } else { |
|---|
| 145 | $this->db = new PDO('sqlite:' . $db); |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | $this->insertKarma = $this->db->prepare(' |
|---|
| 149 | INSERT INTO karmas ( |
|---|
| 150 | word, |
|---|
| 151 | karma |
|---|
| 152 | ) |
|---|
| 153 | VALUES ( |
|---|
| 154 | :word, |
|---|
| 155 | :karma |
|---|
| 156 | ) |
|---|
| 157 | '); |
|---|
| 158 | |
|---|
| 159 | $this->insertComment = $this->db->prepare(' |
|---|
| 160 | INSERT INTO comments ( |
|---|
| 161 | wordid, |
|---|
| 162 | comment |
|---|
| 163 | ) |
|---|
| 164 | VALUES ( |
|---|
| 165 | :wordid, |
|---|
| 166 | :comment |
|---|
| 167 | ) |
|---|
| 168 | '); |
|---|
| 169 | |
|---|
| 170 | $this->fetchKarma = $this->db->prepare(' |
|---|
| 171 | SELECT karma, ROWID id FROM karmas WHERE word = :word LIMIT 1 |
|---|
| 172 | '); |
|---|
| 173 | |
|---|
| 174 | $this->updateKarma = $this->db->prepare(' |
|---|
| 175 | UPDATE karmas SET karma = :karma WHERE word = :word |
|---|
| 176 | '); |
|---|
| 177 | } |
|---|
| 178 | |
|---|
| 179 | |
|---|
| 180 | |
|---|
| 181 | |
|---|
| 182 | |
|---|
| 183 | |
|---|
| 184 | |
|---|
| 185 | |
|---|
| 186 | |
|---|
| 187 | |
|---|
| 188 | public static function checkDependencies(Phergie_Driver_Abstract $client, array $plugins) |
|---|
| 189 | { |
|---|
| 190 | if (!extension_loaded('PDO') |
|---|
| 191 | || !extension_loaded('pdo_sqlite')) { |
|---|
| 192 | return false; |
|---|
| 193 | } |
|---|
| 194 | |
|---|
| 195 | return true; |
|---|
| 196 | } |
|---|
| 197 | |
|---|
| 198 | |
|---|
| 199 | |
|---|
| 200 | |
|---|
| 201 | |
|---|
| 202 | |
|---|
| 203 | |
|---|
| 204 | public function onPrivmsg() |
|---|
| 205 | { |
|---|
| 206 | if ($this->db === null) { |
|---|
| 207 | return; |
|---|
| 208 | } |
|---|
| 209 | $source = $this->event->getSource(); |
|---|
| 210 | $message = $this->event->getArgument(1); |
|---|
| 211 | |
|---|
| 212 | |
|---|
| 213 | $commandPrefix = preg_quote(trim($this->getIni('command_prefix'))); |
|---|
| 214 | $prefix = ($commandPrefix ? $commandPrefix . '|' : '').'(?:' . $this->getIni('nick') . '\s*:?\s+)?'; |
|---|
| 215 | |
|---|
| 216 | |
|---|
| 217 | if (preg_match('#^(?:'.$prefix.')karma\s+(.+)$#i', $message, $m)) { |
|---|
| 218 | |
|---|
| 219 | if (strtolower($m[1]) === 'me') { |
|---|
| 220 | $m[1] = $this->event->getNick(); |
|---|
| 221 | } |
|---|
| 222 | |
|---|
| 223 | $term = $this->doCleanWord($m[1]); |
|---|
| 224 | |
|---|
| 225 | if (isset ($this->fixedKarma[$term])) { |
|---|
| 226 | $this->doPrivmsg($source, sprintf($this->fixedKarma[$term], $m[1]).'.'); |
|---|
| 227 | return; |
|---|
| 228 | } |
|---|
| 229 | |
|---|
| 230 | |
|---|
| 231 | $this->fetchKarma->execute(array(':word'=>$term)); |
|---|
| 232 | $res = $this->fetchKarma->fetch(PDO::FETCH_ASSOC); |
|---|
| 233 | |
|---|
| 234 | |
|---|
| 235 | if (!$res && substr_count($term, ' ') > 1 && !(substr($m[1], 0, 1) === '(' && substr($m[1], -1) === ')')) |
|---|
| 236 | return; |
|---|
| 237 | |
|---|
| 238 | |
|---|
| 239 | if(substr($m[1], 0, 1) === '(' && substr($m[1], -1) === ')') |
|---|
| 240 | $m[1] = substr($m[1], 1, -1); |
|---|
| 241 | |
|---|
| 242 | if ($res && $res['karma'] != 0) { |
|---|
| 243 | $this->doPrivmsg($source, $m[1].' has karma of '.$res['karma'].'.'); |
|---|
| 244 | } else { |
|---|
| 245 | $this->doPrivmsg($source, $m[1].' has neutral karma.'); |
|---|
| 246 | } |
|---|
| 247 | |
|---|
| 248 | } elseif (preg_match('{^(?:'.$prefix.')?(\S+?|\(.+?\)+)(\+{2,}|-{2,})(?:\s+(.*))?$}i', $message, $m)) { |
|---|
| 249 | $word = strtolower($m[1]); |
|---|
| 250 | |
|---|
| 251 | if(substr($word, 0, 1) === '(' && substr($word, -1) === ')') { |
|---|
| 252 | $word = substr($word, 1, -1); |
|---|
| 253 | } else { |
|---|
| 254 | if(strlen($m[2]) > 2) { |
|---|
| 255 | $word .= substr($m[2], 2); |
|---|
| 256 | $m[2] = substr($m[2], -2); |
|---|
| 257 | } |
|---|
| 258 | } |
|---|
| 259 | |
|---|
| 260 | $word = preg_replace('#\s+#', ' ', $word); |
|---|
| 261 | |
|---|
| 262 | if (isset($this->fixedKarma[$word])) { |
|---|
| 263 | return; |
|---|
| 264 | } |
|---|
| 265 | |
|---|
| 266 | if ($word == strtolower($this->event->getNick())) { |
|---|
| 267 | $m[2] = '--'; |
|---|
| 268 | } |
|---|
| 269 | |
|---|
| 270 | $host = $this->event->getHost(); |
|---|
| 271 | $limit = $this->getPluginIni('limit'); |
|---|
| 272 | if (isset ($this->log[$host][$word]) |
|---|
| 273 | && $limit |
|---|
| 274 | && $this->log[$host][$word] > $limit) { |
|---|
| 275 | return; |
|---|
| 276 | } else { |
|---|
| 277 | $this->log[$host][$word] = 0; |
|---|
| 278 | } |
|---|
| 279 | $this->log[$host][$word]++; |
|---|
| 280 | |
|---|
| 281 | $this->fetchKarma->execute(array(':word'=>$word)); |
|---|
| 282 | |
|---|
| 283 | $res = $this->fetchKarma->fetch(PDO::FETCH_ASSOC); |
|---|
| 284 | if ($res) { |
|---|
| 285 | $args = array( |
|---|
| 286 | ':karma' => ($res['karma'] + ($m[2]=='++' ? 1 : -1)), |
|---|
| 287 | ':word' => $word |
|---|
| 288 | ); |
|---|
| 289 | $this->updateKarma->execute($args); |
|---|
| 290 | } else { |
|---|
| 291 | $args = array( |
|---|
| 292 | ':word' => $word, |
|---|
| 293 | ':karma' => ($m[2]=='++' ? '1' : '-1') |
|---|
| 294 | ); |
|---|
| 295 | $this->insertKarma->execute($args); |
|---|
| 296 | $this->fetchKarma->execute(array(':word'=>$word)); |
|---|
| 297 | $res = $this->fetchKarma->fetch(PDO::FETCH_ASSOC); |
|---|
| 298 | } |
|---|
| 299 | $id = $res['id']; |
|---|
| 300 | |
|---|
| 301 | |
|---|
| 302 | $comment = preg_replace('{(?:^//(.*)|^#(.*)|^/\*(.*?)\*/$)}', '$1$2$3', $m[3]); |
|---|
| 303 | if (!empty($comment)) { |
|---|
| 304 | $this->insertComment->execute(array(':wordid' => $id, ':comment' => $comment)); |
|---|
| 305 | } |
|---|
| 306 | |
|---|
| 307 | if (date('d') !== $this->lastGc) { |
|---|
| 308 | $this->doGc(); |
|---|
| 309 | } |
|---|
| 310 | |
|---|
| 311 | } elseif (preg_match('#^([^><]+)(<|>)([^><]+)$#', $message, $m)) { |
|---|
| 312 | |
|---|
| 313 | $word1 = strtolower(trim($m[1])); |
|---|
| 314 | $word2 = strtolower(trim($m[3])); |
|---|
| 315 | $operator = $m[2]; |
|---|
| 316 | |
|---|
| 317 | |
|---|
| 318 | if ($word1 === '*' || $word1 === 'all' || $word1 === 'everything') { |
|---|
| 319 | $res = array('karma' => 0); |
|---|
| 320 | $word1 = 'everything'; |
|---|
| 321 | } else { |
|---|
| 322 | $this->fetchKarma->execute(array(':word'=>$word1)); |
|---|
| 323 | $res = $this->fetchKarma->fetch(PDO::FETCH_ASSOC); |
|---|
| 324 | } |
|---|
| 325 | |
|---|
| 326 | if ($res) { |
|---|
| 327 | if ($word2 === '*' || $word2 === 'all' || $word2 === 'everything') { |
|---|
| 328 | $res2 = array('karma' => 0); |
|---|
| 329 | $word2 = 'everything'; |
|---|
| 330 | } else { |
|---|
| 331 | $this->fetchKarma->execute(array(':word'=>$word2)); |
|---|
| 332 | $res2 = $this->fetchKarma->fetch(PDO::FETCH_ASSOC); |
|---|
| 333 | } |
|---|
| 334 | |
|---|
| 335 | if ($res2 && $res['karma'] != $res2['karma']) { |
|---|
| 336 | $assertion = ($operator === '<' && $res['karma'] < $res2['karma']) || ($operator === '>' && $res['karma'] > $res2['karma']); |
|---|
| 337 | |
|---|
| 338 | if ($operator === '<') { |
|---|
| 339 | $tmp = $word2; $word2 = $word1; $word1 = $tmp; |
|---|
| 340 | } |
|---|
| 341 | $this->doPrivmsg($source, $assertion ? $this->fetchPositiveAnswer($word1, $word2) : $this->fetchNegativeAnswer($word1, $word2) ); |
|---|
| 342 | |
|---|
| 343 | if ($word2 === 'everything') { |
|---|
| 344 | $this->event = clone $this->event; |
|---|
| 345 | $this->event->setArguments(array($this->event->getArgument(0), $word1.'++')); |
|---|
| 346 | $this->onPrivmsg(); |
|---|
| 347 | } elseif ($word1 === 'everything') { |
|---|
| 348 | $this->event = clone $this->event; |
|---|
| 349 | $this->event->setArguments(array($this->event->getArgument(0), $word2.'--')); |
|---|
| 350 | $this->onPrivmsg(); |
|---|
| 351 | } |
|---|
| 352 | } |
|---|
| 353 | } |
|---|
| 354 | } |
|---|
| 355 | } |
|---|
| 356 | |
|---|
| 357 | protected function fetchPositiveAnswer($owner, $owned) { |
|---|
| 358 | return str_replace(array('%owner%','%owned%'), array($owner, $owned), $this->positiveAnswers[array_rand($this->positiveAnswers,1)]); |
|---|
| 359 | } |
|---|
| 360 | |
|---|
| 361 | protected function fetchNegativeAnswer($owned, $owner) { |
|---|
| 362 | return str_replace(array('%owner%','%owned%'), array($owner, $owned), $this->negativeAnswers[array_rand($this->negativeAnswers,1)]); |
|---|
| 363 | } |
|---|
| 364 | |
|---|
| 365 | protected function doCleanWord($word) { |
|---|
| 366 | if(substr($word, 0, 1) === '(' && substr($word, -1) === ')') |
|---|
| 367 | $word = substr($word, 1, -1); |
|---|
| 368 | $word = preg_replace('#\s+#', ' ', strtolower(trim($word))); |
|---|
| 369 | return $word; |
|---|
| 370 | } |
|---|
| 371 | |
|---|
| 372 | |
|---|
| 373 | |
|---|
| 374 | |
|---|
| 375 | |
|---|
| 376 | public function doGc() |
|---|
| 377 | { |
|---|
| 378 | unset ($this->log); |
|---|
| 379 | $this->log = array(); |
|---|
| 380 | $this->lastGc = date('d'); |
|---|
| 381 | } |
|---|
| 382 | } |
|---|