1. <?php
  2. /*
  3. +---------------------------------------------------------------------------
  4. | PHP-IRC v2.2.1 Service Release
  5. | ========================================================
  6. | by Manick
  7. | (c) 2001-2005 by http://www.phpbots.org/
  8. | Contact: manick@manekian.com
  9. | irc: #manekian@irc.rizon.net
  10. | ========================================
  11. +---------------------------------------------------------------------------
  12. | > parser module
  13. | > Module written by Manick
  14. | > Module Version Number: 2.2.0
  15. +---------------------------------------------------------------------------
  16. | > This program is free software; you can redistribute it and/or
  17. | > modify it under the terms of the GNU General Public License
  18. | > as published by the Free Software Foundation; either version 2
  19. | > of the License, or (at your option) any later version.
  20. | >
  21. | > This program is distributed in the hope that it will be useful,
  22. | > but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. | > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. | > GNU General Public License for more details.
  25. | >
  26. | > You should have received a copy of the GNU General Public License
  27. | > along with this program; if not, write to the Free Software
  28. | > Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  29. +---------------------------------------------------------------------------
  30. | Changes
  31. | =======-------
  32. | > If you wish to suggest or submit an update/change to the source
  33. | > code, email me at manick@manekian.com with the change, and I
  34. | > will look to adding it in as soon as I can.
  35. +---------------------------------------------------------------------------
  36. */
  37.  
  38. class parser {
  39.  
  40. private $cmd;
  41. private $args;
  42. private $timers = array();
  43.  
  44. private $cmdList = array();
  45. private $cmdTypes = array();
  46.  
  47. private $fileModified = array();
  48. private $loadDefError = false;
  49.  
  50. //Classes
  51. private $ircClass;
  52. private $dccClass;
  53. private $timerClass;
  54. private $socketClass;
  55. private $db;
  56.  
  57. /* Part of easy alias idea I've been working on..., look below for large bit of commented out code
  58.   for info...
  59.  
  60. private $aliasArray = array( "notice" => "ircClass",
  61. "privMsg" => "ircClass",
  62. "action" => "ircClass",
  63. "sendRaw" => "ircClass",
  64. "getNick" => "ircClass",
  65. "isOnline" => "ircClass",
  66. "isMode" => "ircClass",
  67. "isChanMode" => "ircClass",
  68. "sendFile" => "dccClass",
  69. "dccInform" => "dccClass",
  70. "addTimer" => "timerClass",
  71. "addListener" => "socketClass",
  72. "removeTimer" => "timerClass",
  73. );
  74. */
  75.  
  76. public function __construct() {
  77. $this->fileModified = array();
  78. }
  79.  
  80. public function init()
  81. {
  82.  
  83. if ($this->ircClass->getClientConf('functionfile') != "")
  84. {
  85. $this->loadFuncs($this->ircClass->getClientConf('functionfile'));
  86. }
  87.  
  88. }
  89.  
  90. public function setDccClass($class)
  91. {
  92. $this->dccClass = $class;
  93. }
  94.  
  95. public function setIrcClass($class)
  96. {
  97. $this->ircClass = $class;
  98. }
  99.  
  100. public function setTimerClass($class)
  101. {
  102. $this->timerClass = $class;
  103. }
  104.  
  105. public function setSocketClass($class)
  106. {
  107. $this->socketClass = $class;
  108. }
  109.  
  110. public function setDatabase($class)
  111. {
  112. $this->db = $class;
  113. }
  114.  
  115. public function getCmdList($type = "")
  116. {
  117. if ($type == "")
  118. {
  119. return $this->cmdList;
  120. }
  121. else
  122. {
  123. if (isset($this->cmdList[$type]))
  124. {
  125. return $this->cmdList[$type];
  126. }
  127. else
  128. {
  129. return false;
  130. }
  131. }
  132. }
  133.  
  134. public function destroyModules()
  135. {
  136. if (is_array($this->cmdList) && count($this->cmdList) > 0)
  137. {
  138. if (isset($this->cmdList['file']) && is_array($this->cmdList['file']))
  139. {
  140. foreach ($this->cmdList['file'] AS $index => $data)
  141. {
  142. if (is_object($data['class']))
  143. {
  144. $data['class']->destroy();
  145. }
  146. }
  147. }
  148. }
  149. }
  150.  
  151. private function readFile($file)
  152. {
  153.  
  154. $configRaw = file_get_contents($file);
  155.  
  156. if ($configRaw === false)
  157. {
  158. if (DEBUG == 1)
  159. {
  160. echo "Could not find function file '$file' or error.\n";
  161. }
  162. $this->dccClass->dccInform("Could not find function file '$file' or error.");
  163. return false;
  164. }
  165.  
  166. return $configRaw;
  167.  
  168. }
  169.  
  170. public function include_recurse($file)
  171. {
  172. $configRaw = $this->readFile($file);
  173.  
  174. if ($configRaw === false)
  175. {
  176. return false;
  177. }
  178.  
  179. $configRaw = preg_replace("/;(.*\n?)?/", "\n", $configRaw);
  180. $configRaw = preg_replace("/~.*\n/", "", $configRaw);
  181.  
  182. $configRaw = trim($configRaw);
  183.  
  184. $lines = explode("\n", $configRaw);
  185.  
  186. $num = 0;
  187. $lineNo = 1;
  188. $extra = 0;
  189. $fullLine = "";
  190. foreach ($lines as $line)
  191. {
  192. $line = trim($line);
  193.  
  194. if ($line == "")
  195. {
  196. $lineNo++;
  197. continue;
  198. }
  199.  
  200. $line = trim($fullLine . " " . $line);
  201.  
  202. $newLine = $this->parseFunc($file, $lineNo, $line);
  203.  
  204. $lineNo += $extra + 1;
  205. $extra = 0;
  206. $fullLine = "";
  207.  
  208. if ($newLine === false)
  209. {
  210. continue;
  211. }
  212.  
  213. if ($newLine['type'] == "type")
  214. {
  215. $this->cmdTypes[$newLine['typeArray']['name']]['numArgs'] = count($newLine['typeArray']);
  216. $this->cmdTypes[$newLine['typeArray']['name']]['args'] = $newLine['typeArray'];
  217. }
  218. else if ($newLine['type'] == "include")
  219. {
  220. if (isset($newLine['typeArray'][0]))
  221. {
  222. $num += $this->include_recurse($newLine['typeArray'][0]);
  223. }
  224. else
  225. {
  226. if (DEBUG == 1)
  227. {
  228. echo "Malformed include line on line " . $lineNo . " of function file: " . $file . "\n";
  229. }
  230. $this->dccClass->dccInform("Malformed include line on line " . $lineNo . " of function file: " . $file);
  231. }
  232. }
  233. else
  234. {
  235. if (!isset($newLine['typeArray']['name']))
  236. {
  237. $name = irc::randomHash() . "_" . rand(1,1024);
  238. }
  239. else
  240. {
  241. $name = $newLine['typeArray']['name'];
  242. }
  243.  
  244. unset($newLine['typeArray']['name']);
  245.  
  246. $this->cmdList[$newLine['type']][$name] = $newLine['typeArray'];
  247.  
  248. if (isset($this->cmdList[$newLine['type']][$name]['usage']))
  249. {
  250. if (isset($oldCmdList[$newLine['type']][$name]['usage']))
  251. {
  252. $this->cmdList[$newLine['type']][$name]['usage'] = $oldCmdList[$newLine['type']][$name]['usage'];
  253. }
  254. }
  255.  
  256. }
  257.  
  258. $num++;
  259. }
  260.  
  261. return $num;
  262. }
  263.  
  264.  
  265.  
  266.  
  267. public function loadFuncs($file)
  268. {
  269. $error = false;
  270.  
  271. clearstatcache();
  272.  
  273. $this->destroyModules();
  274.  
  275. $oldCmdList = $this->cmdList;
  276. if (!is_array($oldCmdList))
  277. {
  278. $oldCmdList = array();
  279. }
  280.  
  281. unset($this->cmdList);
  282. unset($this->cmdTypes);
  283. $this->cmdList = array();
  284. $this->cmdTypes = array();
  285.  
  286. $this->dccClass->dccInform("Rehashing Function File, please wait...");
  287. if (DEBUG == 1)
  288. {
  289. echo "Rehashing Function File, please wait...\n";
  290. }
  291.  
  292. //Read in main function file
  293. $num = $this->include_recurse($file);
  294.  
  295. //Book keeping
  296. foreach ($this->cmdList AS $cmd => $data)
  297. {
  298. ksort($this->cmdList[$cmd]);
  299. }
  300.  
  301. if (isset($this->cmdList['file']))
  302. {
  303. foreach ($this->cmdList['file'] AS $file => $data)
  304. {
  305.  
  306. $classDef = $this->loadClassDef($data['filename'], $file);
  307.  
  308. if ($this->loadDefError == true)
  309. {
  310. $error = true;
  311. }
  312. $this->loadDefError = false;
  313.  
  314. if ($classDef === false)
  315. {
  316. continue;
  317. }
  318.  
  319. //require_once($data['filename']);
  320.  
  321. $this->cmdList['file'][$file]['class'] = new $classDef;
  322.  
  323. $this->cmdList['file'][$file]['class']->__setClasses( $this->ircClass,
  324. $this->dccClass,
  325. $this->timerClass,
  326. $this,
  327. $this->socketClass,
  328. $this->db
  329. );
  330. $this->cmdList['file'][$file]['class']->init();
  331. }
  332. }
  333.  
  334. $this->dccClass->dccInform("Successfully loaded " . $num . " functions into memory.");
  335. if (DEBUG == 1)
  336. {
  337. echo "Successfully loaded " . $num . " functions into memory.\n";
  338. }
  339.  
  340. return $error;
  341.  
  342. }
  343.  
  344. private function loadClassError($filename, $msg)
  345. {
  346. $this->ircClass->log("Error loading $filename: $msg");
  347. $this->dccClass->dccInform("Error loading $filename: $msg");
  348. }
  349.  
  350. /* Okay..
  351. * This method is really freaking cool. It loads a module file with fopen, then
  352. * it finds the classname, and gives it a random name (changes it) so that you can
  353. * include functions you've changed multiple times without having to restart the bot!
  354. * Also, easier names than having to use $this->ircClass->blah() all the time, you can
  355. * just use blah()... These are defined in an array somewhere... I'm not sure where yet...
  356. * because I haven't written that yet!!!!!!!!!!!!111oneone.
  357. */
  358.  
  359. private function loadClassDef($filename, $classname)
  360. {
  361.  
  362. $stat = stat($filename);
  363.  
  364. if ($stat === false)
  365. {
  366. $this->loadClassError($filename, "Could not find function file");
  367. return false;
  368. }
  369.  
  370. $modified = $stat['mtime'];
  371.  
  372. if (isset($this->fileModified[$filename]))
  373. {
  374. if ($modified == $this->fileModified[$filename]['modified'])
  375. {
  376. return $this->fileModified[$filename]['classdef'];
  377. }
  378. }
  379.  
  380. $fileData = file_get_contents($filename);
  381.  
  382. if ($fileData === false)
  383. {
  384. $this->loadClassError($filename, "Could not find function file");
  385. return false;
  386. }
  387.  
  388. //Okay, we have the module now.. now we need to find some stuff.
  389.  
  390. if (!preg_match("/class[\s]+?".$classname."[\s]+?extends[\s]+?module[\s]+?{/", $fileData))
  391. {
  392. $this->loadClassError($filename, "Could not find valid classdef in function file");
  393. return false;
  394. }
  395.  
  396. //Okay, our module is in the file... replace it with random hash.
  397.  
  398. $newHash = irc::randomHash();
  399.  
  400. $newClassDef = $classname . "_" . $newHash;
  401.  
  402. $fileData = preg_replace("/(class[\s]+?)".$classname."([\s]+?extends[\s]+?module[\s]+?{)/", "\\1" . $newClassDef . "\\2", $fileData);
  403.  
  404. /* Interesting idea, but lets leave it out for now
  405. foreach($this->aliasArray AS $func => $class)
  406. {
  407. $fileData = preg_replace("/([=\n\(\t\s]+?)".$func."[\s\t\n\r]*?\(/s", "\\1\$this->" . $class . "->" . $func . "(", $fileData);
  408. }
  409. */
  410.  
  411. $success = eval("?>" . $fileData . "<?php ");
  412.  
  413. if ($success === false)
  414. {
  415. $this->loadClassError($filename, "Error in function file");
  416.  
  417. /* Attempt to fallback on a previous revision that worked! */
  418. if (isset($this->fileModified[$filename]))
  419. {
  420. $this->loadClassError($filename, "Using a cached version of the class definition");
  421. $this->loadDefError = true;
  422. return $this->fileModified[$filename]['classdef'];
  423. }
  424.  
  425. return false;
  426. }
  427.  
  428. $this->fileModified[$filename]['modified'] = $modified;
  429. $this->fileModified[$filename]['classdef'] = $newClassDef;
  430.  
  431. return $newClassDef;
  432.  
  433. }
  434.  
  435. //Used to show array, as there seems to be some crazy bug in var_dump/print_r that
  436. //shows EVERY variable in my program when I do var_dump($this->cmdList) or use print_r the same way
  437. //This isn't used anywhere in the production copy of this script. (DEBUG ONLY!)
  438. private function show_all($title, $array, $level)
  439. {
  440. echo $title . " = array(" . "\r\n";
  441.  
  442. foreach($array AS $index => $val)
  443. {
  444. for ($i = 0; $i < $level; $i++)
  445. {
  446. echo " ";
  447. }
  448.  
  449. if (is_array($val))
  450. {
  451. $this->show_all($index, $val, $level + 1);
  452. }
  453. else if (is_object($val))
  454. {
  455. echo "[$index] => [object]\r\n";
  456. }
  457. else
  458. {
  459. echo "[$index] => [$val]\r\n";
  460. }
  461. }
  462.  
  463. for ($i = 0; $i < $level; $i++)
  464. {
  465. echo " ";
  466. }
  467.  
  468. echo ")\r\n";
  469.  
  470. }
  471.  
  472. public function setCmdListValue($type, $cmd, $var, $value)
  473. {
  474. if (isset($this->cmdList[$type][$cmd][$var]))
  475. {
  476. $this->cmdList[$type][$cmd][$var] = $value;
  477. return true;
  478. }
  479. return false;
  480. }
  481.  
  482. private function parseFunc($file, $lineNo, $line)
  483. {
  484. $strings = array();
  485. $line = str_replace("\t", " ", $line);
  486.  
  487. $quotes = array("'", "\"");
  488.  
  489. foreach($quotes AS $quote)
  490. {
  491. $currPos = 0;
  492. $extraPos = 0;
  493. while (($firstPos = strpos($line, $quote, $currPos)) !== false && substr($line, strpos($line, $quote, $currPos)-1, 1) != "\\")
  494. {
  495.  
  496. while (($secondPos = strpos($line, $quote, $firstPos + 1 + $extraPos)) !== false && substr($line, strpos($line, $quote, $firstPos + 1 + $extraPos)-1, 1) == "\\")
  497. {
  498. $extraPos = $secondPos;
  499. }
  500.  
  501. if ($secondPos === false)
  502. {
  503. if (DEBUG == 1)
  504. {
  505. echo "Syntax Error on line " . $lineNo . " of function file: " . $file . ". Expected '".$quote."', got end of line.\n";
  506. }
  507. $this->dccClass->dccInform("Syntax Error on line " . $lineNo . " of function file: " . $file . ". Expected '".$quote."', got end of line.");
  508. return false;
  509. }
  510.  
  511. $strings[$quote][] = substr($line, $firstPos + 1, $secondPos - $firstPos - 1);
  512. $currPos = $secondPos + 1;
  513. }
  514. }
  515.  
  516. foreach ($strings AS $string)
  517. {
  518. $line = str_replace($string, "", $line);
  519. }
  520.  
  521. $lineElements = explode(chr(32), $line);
  522.  
  523. $type = "";
  524. $currElement = 0;
  525. $typeArray = array();
  526.  
  527. foreach($lineElements AS $element)
  528. {
  529. if (trim($element) == "")
  530. {
  531. continue;
  532. }
  533.  
  534. $currElement++;
  535.  
  536. if ($currElement == 1)
  537. {
  538. $element = irc::myStrToLower($element);
  539.  
  540. if ($element == "type")
  541. {
  542. $type = "type";
  543. }
  544. else if ($element == "include")
  545. {
  546. $type = "include";
  547. }
  548. else
  549. {
  550. if (isset($this->cmdTypes[$element]))
  551. {
  552. $type = $element;
  553. }
  554. else
  555. {
  556. if (DEBUG == 1)
  557. {
  558. echo "Error: Undefined type, '" . $element . "' on line " . $lineNo . " of function file: " . $file . "\n";
  559. }
  560. $this->dccClass->dccInform("Error: Undefined type, '" . $element . "' on line " . $lineNo . " of function file: " . $file . "");
  561. return false;
  562. }
  563. }
  564. continue;
  565. }
  566.  
  567. if ($element == "\"\"")
  568. {
  569. $element = array_shift($strings["\""]);
  570. }
  571. else if ($element == "''")
  572. {
  573. $element = array_shift($strings["'"]);
  574. }
  575.  
  576. $element = str_replace("\\" . "'", "'", $element);
  577. $element = str_replace("\\" . '"', '"', $element);
  578.  
  579. if ($type == "type")
  580. {
  581. if ($currElement == 2)
  582. {
  583. $typeArray['name'] = $element;
  584. }
  585. else
  586. {
  587. $typeArray[] = $element;
  588. }
  589. }
  590. else if ($type == "include")
  591. {
  592. $typeArray[] = $element;
  593. }
  594. else
  595. {
  596. if ($currElement > $this->cmdTypes[$type]['numArgs'])
  597. {
  598. if (DEBUG == 1)
  599. {
  600. echo "Error on line " . $lineNo . " of function file: " . $file . ", too many arguments\n";
  601. }
  602. $this->dccClass->dccInform("Error on line " . $lineNo . " of function file: " . $file . ", too many arguments");
  603. return false;
  604. }
  605.  
  606. $element = (irc::myStrToLower($element) == "true" ? true : $element);
  607. $element = (irc::myStrToLower($element) == "false" ? false : $element);
  608.  
  609. $typeArray[$this->cmdTypes[$type]['args'][ $currElement - 2 ]] = $element;
  610. }
  611.  
  612.  
  613. }
  614.  
  615. if ($type != "type" && $type != "include")
  616. {
  617. if ($currElement < $this->cmdTypes[$type]['numArgs'])
  618. {
  619. if (DEBUG == 1)
  620. {
  621. echo "Error on line " . $lineNo . " of function file: " . $file . ", not enough arguments\n";
  622. }
  623. $this->dccClass->dccInform("Error on line " . $lineNo . " of function file: " . $file . ", not enough arguments");
  624. return false;
  625. }
  626. }
  627.  
  628. return array('type' => $type, 'typeArray' => $typeArray);
  629.  
  630. }
  631.  
  632.  
  633.  
  634. public function parseDcc($chat, $handler)
  635. {
  636.  
  637. $chat->readQueue = str_replace("\r", "", $chat->readQueue);
  638.  
  639. // if (!($offSet = strpos($chat->readQueue, "\n")))
  640. // {
  641. // return false;
  642. // }
  643. // $rawLine = trim(substr($chat->readQueue, 0, $offSet));
  644. // $chat->readQueue = substr($chat->readQueue, $offSet + 1);
  645.  
  646. $rawLine = $chat->readQueue;
  647. $chat->readQueue = "";
  648.  
  649. $this->ircClass->log("DCC Chat(" . $chat->nick . "): " . $rawLine);
  650.  
  651. $line = $this->createLine($rawLine);
  652.  
  653. if ($line == false)
  654. {
  655. return;
  656. }
  657.  
  658. if ($handler != false)
  659. {
  660. if (is_object($handler))
  661. {
  662. $handler->handle($chat, $line);
  663. return;
  664. }
  665. }
  666.  
  667. if ($chat->isAdmin == true && $chat->verified == false)
  668. {
  669. if (md5($line['cmd']) == $this->ircClass->getClientConf('dccadminpass'))
  670. {
  671. $this->dccClass->dccInform("DCC: " . $chat->nick . " has successfully logged in.");
  672. $chat->verified = true;
  673. $chat->dccSend("You have successfully logged in.");
  674.  
  675. }
  676. else
  677. {
  678. $chat->dccSend("Invalid password, bye bye.");
  679. $this->dccClass->disconnect($chat);
  680. }
  681. return;
  682. }
  683.  
  684. $cmdLower = irc::myStrToLower($line['cmd']);
  685.  
  686. if (isset($this->cmdList['dcc'][$cmdLower]))
  687. {
  688. if ($this->cmdList['dcc'][$cmdLower]['admin'] == 1 && !$chat->isAdmin)
  689. {
  690. $chat->dccSend("Request Denied. You must have admin access to use this function.");
  691. return;
  692. }
  693.  
  694. if ($line['nargs'] < $this->cmdList['dcc'][$cmdLower]['numArgs'])
  695. {
  696. $chat->dccSend("Usage: " . $cmdLower . " " . $this->cmdList['dcc'][$cmdLower]['usage']);
  697. return;
  698. }
  699.  
  700. $module = $this->cmdList['dcc'][$cmdLower]['module'];
  701. $class = $this->cmdList['file'][$module]['class'];
  702. $func = $this->cmdList['dcc'][$cmdLower]['function'];
  703.  
  704. $class->$func($chat, $line);
  705.  
  706. if ($chat->isAdmin)
  707. {
  708. $chat->dccSend("ADMIN " . irc::myStrToUpper($cmdLower) . " Requested");
  709. }
  710. else
  711. {
  712. $chat->dccSend("CLIENT " . irc::myStrToUpper($cmdLower) . " Requested");
  713. }
  714. }
  715. else
  716. {
  717. $chat->dccSend("Invalid Command: " . $line['cmd']);
  718. }
  719.  
  720. }
  721.  
  722.  
  723. public static function createLine($rawLine)
  724. {
  725.  
  726. $line = array();
  727. $rawLineArray = explode(chr(32), $rawLine);
  728. $lineCount = count($rawLineArray);
  729.  
  730. if ($lineCount < 1)
  731. {
  732. return false;
  733. }
  734. else if ($lineCount == 1)
  735. {
  736. $line['cmd'] = irc::myStrToLower($rawLine);
  737. $line['nargs'] = 0;
  738. $line['query'] = "";
  739. }
  740. else
  741. {
  742. $line['nargs'] = 0;
  743. $line['cmd'] = irc::myStrToLower(array_shift($rawLineArray));
  744. while (($arg = array_shift($rawLineArray)) !== NULL) // NULL fixed contributed by cortex, 05/01/05
  745. {
  746. if (trim($arg) == "")
  747. {
  748. continue;
  749. }
  750.  
  751. $line['arg' . ++$line['nargs']] = $arg;
  752. if ($line['nargs'] > MAX_ARGS-1)
  753. {
  754. break;
  755. }
  756. }
  757. $line['query'] = trim(substr($rawLine, strlen($line['cmd']) + 1));
  758. }
  759.  
  760. return $line;
  761.  
  762. }
  763.  
  764. public function parseLine($line)
  765. {
  766. if (DEBUG==1)
  767. {
  768. //print_r($line);
  769. }
  770.  
  771. if ($this->ircClass->checkIgnore($line['from']))
  772. {
  773. return;
  774. }
  775.  
  776. switch($line['cmd'])
  777. {
  778. case "PRIVMSG":
  779. $args = $this->createLine($line['text']);
  780. $cmdLower = irc::myStrToLower($args['cmd']);
  781. if (isset($this->cmdList['priv'][$cmdLower]))
  782. {
  783. if ($this->cmdList['priv'][$cmdLower]['active'] == true)
  784. {
  785. $theCase = $this->ircClass->floodCheck($line);
  786.  
  787. switch ($theCase)
  788. {
  789. case STATUS_NOT_BANNED:
  790. if ($this->cmdList['priv'][$cmdLower]['inform'] == true)
  791. {
  792. $this->dccClass->dccInform("Sending " . irc::myStrToUpper($line['text']) . " to " . $line['fromNick']);
  793. }
  794. $this->cmdList['priv'][$cmdLower]['usage']++;
  795. $func = $this->cmdList['priv'][$cmdLower]['function'];
  796. $module = $this->cmdList['priv'][$cmdLower]['module'];
  797. $class = $this->cmdList['file'][$module]['class'];
  798.  
  799. if ($this->ircClass->getTextQueueLength() > 5)
  800. {
  801. $this->ircClass->notice($line['fromNick'], "Request Queued. Please wait " . $this->ircClass->getTextQueueLength() . " seconds for your data.", 0);
  802. }
  803.  
  804. $class->$func($line, $args);
  805. break;
  806. case STATUS_JUST_BANNED:
  807. $this->ircClass->notice($line['fromNick'], "Flood Detected. All of your queues have been discarded and you have been banned from using this bot for ". $this->ircClass->getClientConf('floodtime') . " seconds.");
  808. $this->dccClass->dccInform("BAN: (*!". irc::myStrToUpper($line['fromHost']) . "): " . $line['fromNick'] . " is on ignore for " . $this->ircClass->getClientConf('floodtime') . " seconds.");
  809. break;
  810. case STATUS_ALREADY_BANNED:
  811. break;
  812. }
  813. }
  814. else
  815. {
  816. $this->dccClass->dccInform("FUNCTION: " . $line['fromNick'] . " attempted to use deactivated command '" . $cmdLower . "'");
  817. }
  818. }
  819. else
  820. {
  821. if ($line['to'] == $this->ircClass->getNick())
  822. {
  823. if (strpos($line['text'], chr(1)) !== false)
  824. {
  825. $this->ircClass->floodCheck($line);
  826. $this->parseCtcp($line);
  827. }
  828. else
  829. {
  830. $this->dccClass->dccInform("PRIVMSG: <" . $line['fromNick'] . "> " . $line['text']);
  831. }
  832. }
  833. else
  834. {
  835. if (strpos($line['text'], chr(1)) !== false)
  836. {
  837. $this->parseCtcp($line, "CHAN: " . $line['to']);
  838. }
  839. else
  840. {
  841. $chanData = $this->ircClass->getChannelData($line['to']);
  842.  
  843. if ($chanData == NULL)
  844. {
  845. $this->dccClass->dccInform("CHAN PRIVMSG [".$line['to']."]: <" . $line['fromNick'] . "> " . $line['text']);
  846. }
  847. }
  848. }
  849. }
  850. break;
  851.  
  852. case "MODE":
  853. break;
  854.  
  855. case "NOTICE":
  856. $chan = $line['to'] != $this->ircClass->getNick() ? ":" . $line['to'] : "";
  857. $this->dccClass->dccInform("NOTICE: <" . ($line['fromNick'] == "" ? $line['from'] : $line['fromNick']) . $chan . "> " . $line['text']);
  858. break;
  859.  
  860. case "JOIN":
  861. if ($line['fromNick'] == $this->ircClass->getNick())
  862. {
  863. $this->dccClass->dccInform("Joined: " . irc::myStrToUpper($line['text']));
  864. }
  865. break;
  866.  
  867. case "PART":
  868. if ($line['fromNick'] == $this->ircClass->getNick())
  869. {
  870. $this->dccClass->dccInform("Parted: " . irc::myStrToUpper($line['to']));
  871. }
  872. break;
  873.  
  874. case "KICK":
  875. if ($line['params'] == $this->ircClass->getNick())
  876. {
  877. $this->dccClass->dccInform("Kicked: " . $line['fromNick'] . " kicked you from " . $line['to']);
  878. }
  879. break;
  880.  
  881. case "ERROR":
  882. $this->dccClass->dccInform("Server Error: " . $line['text']);
  883. break;
  884.  
  885. case "366":
  886. $params = explode(chr(32), $line['params']);
  887. $channel = $params[0];
  888. $this->dccClass->dccInform("Finished receiving NAMES list for " . $channel);
  889. break;
  890.  
  891. case "005":
  892. if ($this->ircClass->getServerConf("NETWORK") != "")
  893. {
  894. //Only show this once...
  895. if (strpos($line['params'],"NETWORK") !== false)
  896. {
  897. $this->dccClass->dccInform("Parsing IRC-Server specific configuration...");
  898. $this->dccClass->dccInform("Network has been identified as " . $this->ircClass->getServerConf("NETWORK") .
  899. "(" . $line['from'] . ")");
  900. }
  901. }
  902. break;
  903.  
  904. case "315":
  905. $params = explode(chr(32), $line['params']);
  906. $this->dccClass->dccInform("Finished receiving WHO list for: " . $params[0]);
  907. break;
  908.  
  909. case "368":
  910. $params = explode(chr(32), $line['params']);
  911. $this->dccClass->dccInform("Finished receiving ban list for: " . $params[0]);
  912. break;
  913.  
  914. case "433":
  915. $this->dccClass->dccInform("Nick collision! Unable to change your nick. Nickname already in use!");
  916. break;
  917.  
  918. default:
  919. break;
  920.  
  921. }
  922.  
  923. // Lets alias 004 to CONNECT, for the n00bs
  924.  
  925. if ($line['cmd'] == "004")
  926. {
  927. $line['cmd'] = "connect";
  928. }
  929. if ($line['cmd'] == "error")
  930. {
  931. $line['cmd'] = "disconnect";
  932. }
  933.  
  934. // Action type handler
  935. if (isset($this->cmdList['action']) && strtolower($line['cmd']) == "privmsg")
  936. {
  937. if (substr($line['text'], 0, 8) == chr(1) . "ACTION ")
  938. {
  939. $newLine = $line;
  940. $newLine['text'] = substr($line['text'], 8, strlen($line['text']) - 9);
  941.  
  942. $sArgs = $this->createLine($newLine['text']);
  943.  
  944. foreach($this->cmdList['action'] AS $item)
  945. {
  946. $func = $item['function'];
  947. $class = $this->cmdList['file'][$item['module']]['class'];
  948. $class->$func($newLine, $sArgs);
  949. }
  950. }
  951. }
  952.  
  953. // Raw type handler
  954. if (isset($this->cmdList['raw']))
  955. {
  956. if (!isset($args))
  957. {
  958. $args = $this->createLine($line['text']);
  959. }
  960.  
  961. foreach($this->cmdList['raw'] AS $item)
  962. {
  963. $func = $item['function'];
  964. $class = $this->cmdList['file'][$item['module']]['class'];
  965. $class->$func($line, $args);
  966. }
  967. }
  968.  
  969.  
  970. // Here we will call any type
  971.  
  972. if (isset($this->cmdList[irc::myStrToLower($line['cmd'])]))
  973. {
  974. if (!isset($args))
  975. {
  976. $args = $this->createLine($line['text']);
  977. }
  978.  
  979. foreach($this->cmdList[irc::myStrToLower($line['cmd'])] AS $item)
  980. {
  981. $func = $item['function'];
  982. $class = $this->cmdList['file'][$item['module']]['class'];
  983. $class->$func($line, $args);
  984. }
  985. }
  986.  
  987. if (isset($args))
  988. {
  989. unset($args);
  990. }
  991.  
  992. }
  993.  
  994.  
  995. /* Misc Functions */
  996.  
  997. private function parseCtcp($line, $msgs = "PRIVMSG")
  998. {
  999. $cmd = str_replace(chr(1), "", $line['text']) . " ";
  1000. $query = trim(substr($cmd, strpos($cmd, chr(32)) + 1));
  1001. $cmd = substr(irc::myStrToLower($cmd), 0, strpos($cmd, chr(32)));
  1002.  
  1003. $msg = "";
  1004.  
  1005. switch($cmd)
  1006. {
  1007. case "version":
  1008. $this->dccClass->dccInform("CTCP VERSION: " . $line['fromNick'] . " versioned us.");
  1009. break;
  1010.  
  1011. case "time":
  1012. $this->dccClass->dccInform("CTCP TIME: " . $line['fromNick'] . " requested the time.");
  1013. break;
  1014.  
  1015. case "uptime":
  1016. $this->dccClass->dccInform("CTCP UPTIME: " . $line['fromNick'] . " requested our uptime.");
  1017. break;
  1018.  
  1019. case "ping":
  1020. $this->dccClass->dccInform("CTCP PING: " . $line['fromNick'] . " pinged us.");
  1021. break;
  1022.  
  1023. case "dcc":
  1024. $vars = explode(chr(32), $query);
  1025. $this->dccParse($line, $vars, $query);
  1026. break;
  1027.  
  1028. }
  1029.  
  1030. if ($msg != "")
  1031. {
  1032. $this->notice($this->lVars['fromNick'], chr(1) . $msg . chr(1));
  1033. }
  1034.  
  1035. if (isset($this->cmdList['ctcp'][$cmd]))
  1036. {
  1037. $func = $this->cmdList['ctcp'][$cmd]['function'];
  1038. $class = $this->cmdList['file'][$this->cmdList['ctcp'][$cmd]['module']]['class'];
  1039. $args = $this->createLine($cmd . " " . $query);
  1040. $class->$func($line, $args);
  1041. }
  1042.  
  1043. }
  1044.  
  1045. function dccParse($line, $vars, $txt)
  1046. {
  1047. $cVars = count($vars);
  1048.  
  1049. if ($cVars < 1)
  1050. {
  1051. return;
  1052. }
  1053.  
  1054. $cmd = irc::myStrToUpper($vars[0]);
  1055.  
  1056. switch ($cmd)
  1057. {
  1058. case "CHAT":
  1059. if ($cVars == 4)
  1060. {
  1061. $iplong = long2ip( (double) $vars[2]);
  1062. $port = $vars[3];
  1063. $this->dccClass->addChat($line['fromNick'], $iplong, (int) $port, false, null);
  1064. }
  1065. break;
  1066. case "SEND":
  1067. if ($this->ircClass->getClientConf('upload') != 'yes')
  1068. {
  1069. $this->ircClass->notice($line['fromNick'], "DCC: I do not accept dcc transfers at this time.", 0);
  1070. break;
  1071. }
  1072. if ($cVars >= 5)
  1073. {
  1074. //Some bastard sent a file with spaces. Shit. Ass.
  1075. if (strpos($query, chr(34)) !== false)
  1076. {
  1077. $first = strpos($query, chr(34));
  1078. $second = strpos($query, chr(34), $first + 1);
  1079. $filename = substr($query, $first + 1, $second - $first - 1);
  1080. $query = str_replace("\"".$filename."\"", "file.ext", $query);
  1081. $vars = explode(chr(32), $query);
  1082. }
  1083. else
  1084. {
  1085. $filename = $vars[1];
  1086. }
  1087.  
  1088. $iplong = long2ip( (double) $vars[2]);
  1089. $port = $vars[3];
  1090. $filesize = $vars[4];
  1091.  
  1092. $this->dccClass->addFile($line['fromNick'], $iplong, (int) $port, DOWNLOAD, $filename, $filesize);
  1093. }
  1094. break;
  1095. case "ACCEPT":
  1096. if ($cVars == 4)
  1097. {
  1098. $port = $vars[2];
  1099. $bytes = $vars[3];
  1100. $this->dccClass->dccAccept($port, $bytes);
  1101. }
  1102. break;
  1103. case "RESUME":
  1104. if ($cVars == 4)
  1105. {
  1106. $port = $vars[2];
  1107. $bytes = $vars[3];
  1108. $this->dccClass->dccResume($port, $bytes);
  1109. }
  1110. break;
  1111. }
  1112.  
  1113. }
  1114.  
  1115. }
  1116.  
  1117. /* Used to access dcc admin commands via private message */
  1118. class chat_wrapper {
  1119.  
  1120. public $nick;
  1121. private $ircClass;
  1122. public $isAdmin;
  1123.  
  1124. public function __construct($nick, $ircClass)
  1125. {
  1126. $this->nick = $nick;
  1127. $this->ircClass = $ircClass;
  1128. $this->isAdmin = 1;
  1129. }
  1130.  
  1131. public function dccSend($data, $to = null)
  1132. {
  1133. $this->ircClass->privMsg($this->nick, "--> " . $data);
  1134. }
  1135.  
  1136. public function disconnect($msg = "")
  1137. {
  1138. $this->ircClass->privMsg($this->nick, "Right........");
  1139. }
  1140.  
  1141. }
  1142.  
  1143. ?>
  1144.