Source for file class.Commands.inc

Documentation is available at class.Commands.inc

  1. <?php //-*-php-*-
  2. /* ******************************************************************** **
  3. ** Copyright notice **
  4. ** **
  5. ** (c) 1995-2003 PHPOpenChat Development Team **
  6. ** http://phpopenchat.sourceforge.net/ **
  7. ** **
  8. ** All rights reserved **
  9. ** **
  10. ** This script is part of the PHPOpenChat project. The PHPOpenChat **
  11. ** project is free software; you can redistribute it and/or modify **
  12. ** it under the terms of the GNU General Public License as published by **
  13. ** the Free Software Foundation; either version 2 of the License, or **
  14. ** (at your option) any later version. **
  15. ** **
  16. ** The GNU General Public License can be found at **
  17. ** http://www.gnu.org/copyleft/gpl.html. **
  18. ** A copy is found in the textfile GPL and important notices to the **
  19. ** license from the team is found in the textfile LICENSE distributed **
  20. ** with these scripts. **
  21. ** **
  22. ** This script is distributed in the hope that it will be useful, **
  23. ** but WITHOUT ANY WARRANTY; without even the implied warranty of **
  24. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
  25. ** GNU General Public License for more details. **
  26. ** **
  27. ** This copyright notice MUST APPEAR in all copies of the script! **
  28. ** ******************************************************************** */
  29.  
  30. require_once('config.inc.php');
  31. require_once(POC_INCLUDE_PATH.'/definitions.inc');
  32. require_once(POC_INCLUDE_PATH.'/functions.inc');
  33. require_once(POC_INCLUDE_PATH.'/class.Response.inc');
  34. require_once(POC_INCLUDE_PATH.'/class.Line.inc');
  35.  
  36.  
  37. function _chatter_is_away($rec) {
  38. // $rec == string for now
  39. // returns false or away msg (maybe empty)
  40.  
  41. if( $rec == '###EVERYBODY###') {
  42. return(false);
  43. }
  44. else {
  45. $_SESSION['chat']->connect();
  46. $away_msg = $_SESSION['chat']->is_away( $rec );
  47. $_SESSION['chat']->disconnect();
  48. return ($away_msg);
  49. }
  50. }
  51.  
  52. /**
  53. * Checks the posted string and replaces the forbidden words with 'Ooops'
  54. *
  55. * @package phpopenchat
  56. * @param string $string
  57. * @param array $forbidden_strings
  58. * @return string
  59. */
  60. function check_chat( $string, $forbidden_strings ) {
  61. if(! is_array($forbidden_strings) ) die('forbidden_strings: Array expected!');
  62. if( count($forbidden_strings) == 0 ) return $string;
  63. $chars= '[\.\-\'\(\=\?\/\|)_,;:!"`§$%& ]';
  64. do{
  65. $search_string = chunk_split(current($forbidden_strings), 1, $chars.'*');
  66. $string = preg_replace('/'.$search_string.'/','<acronym title="'.$_SESSION['translator']->out('FORBIDDEN_WORD').'">...Ooops...</acronym>',$string);
  67. }while( next($forbidden_strings) );
  68. unset($search_string);
  69. unset($chars);
  70. return $string;
  71. }
  72.  
  73.  
  74.  
  75. function NewLineFromBot () {
  76. $line =& new Line( null , "" );
  77. $bot =& new Chatter(strval(STATUS_BOT_NAME),'');
  78. $line->set_sender($bot);
  79. $line->set_channel( $_SESSION['channel']->get_name() );
  80. unset($bot);
  81. return ($line);
  82. }
  83.  
  84. function _response_to_me ($msg = '' ) {
  85. $res=& new Response();
  86. $res->line = NewLineFromBot();
  87. $res->line->set_said($msg);
  88. $res->line->set_recipient($_SESSION['chatter']);
  89. // $res->line->set_approved();
  90. $res->show_local = true;
  91. return($res);
  92. }
  93.  
  94.  
  95. function _handle_away() {
  96. deb("entering handle_away", 'dataflow');
  97. if ( ! ( _chatter_is_away($_SESSION['chatter']->get_nick() ) === false ) ) {
  98. $res =& new Response();
  99. $res->line =& NewLineFromBot();
  100. $res->line->set_said( $_SESSION['translator']->out('HINT_YOU_ARE_AFK') );
  101. $res->line->set_recipient($_SESSION['chatter']);
  102. $res->line->set_approved();
  103. $res->comment='msg to '.$this->PlainSender.' that (s)he is afk';
  104. $res->show_local = true;
  105. return($res);
  106. }
  107. return(null);
  108. }
  109.  
  110. function _channel_exists($channel) {
  111. /* // test if channel exists
  112. $channels = array();
  113. $_SESSION['chat']->connect();
  114. $channels = $_SESSION['chat']->get_channels();
  115. $_SESSION['chat']->disconnect();
  116. return ( in_array(strval($channel), $channels) );
  117. */
  118. $_SESSION['chat']->connect();
  119. $exist = $_SESSION['chat']->channel_exists($channel);
  120. $_SESSION['chat']->disconnect();
  121.  
  122. return($exist);
  123. }
  124.  
  125.  
  126. /**
  127. * Implements a irc-like command within the chat
  128. *
  129. * @package phpopenchat
  130. */
  131. class Command {
  132. var $error = '';
  133.  
  134. function Command () {
  135. }
  136.  
  137. function get ($key) {
  138. if ( isset($this->$key) ) {
  139. return ($this->$key);
  140. }
  141. else {
  142. // return (undef);
  143. deb("key $key undefined");
  144. die("key $key undefined");
  145. }
  146. }
  147. function set($key, $val) {
  148. if (isset($this->$key)) {
  149. $this->$key = $val;
  150. }
  151. else {
  152. deb("key $key undefined");
  153. die("key $key undefined");
  154. // return(undef);
  155. }
  156. }
  157. }
  158.  
  159. /**
  160. * Implements a irc-like command line within the chat
  161. *
  162. * @package phpopenchat
  163. */
  164. class _ChatlineCommand extends Command {
  165. var $from = '';
  166. var $to = '';
  167. var $channel = '';
  168. var $whispered = '';
  169. var $what = '';
  170.  
  171. function _ChatlineCommand ( $from, $to, $channel, $what, $whispered ) {
  172. $this->from = $from;
  173. $this->to = $to;
  174. $this->channel = $channel;
  175. $this->what = $what;
  176. $this->whispered = $whispered;
  177. }
  178.  
  179. function run () {
  180. deb("running _ChatlineCommand");
  181. $allres = array();
  182.  
  183. // if line is empty do nothing.
  184. if (! $this->what) {
  185. $res =& _response_to_me('');
  186. $res->show_local = false;
  187. $res->show_remote = false;
  188. $res->comment='empty line';
  189. deb("empty line");
  190. return($res);
  191. }
  192.  
  193. // Bug: for now "from" has to be the same as $_SESSION['chatter']->get_nick()
  194. // test if from and to are online
  195. $_SESSION['chat']->connect();
  196. if ( ! $_SESSION['chat']->is_online($this->from) || ! $this->from == $_SESSION['chatter']->get_nick() ) {
  197. // should not happen, but handle anyway
  198. deb("chatter is not online");
  199. die ("you are not online!");
  200. }
  201. if ( ! $_SESSION['chat']->is_online($this->to) ) {
  202. deb("to is not online");
  203. $res =& _response_to_me($this->to." ".$_SESSION['translator']->out('IS_NOT_ONLINE') );
  204. return($res);
  205. }
  206. $_SESSION['chat']->disconnect();
  207.  
  208. // test if from is afk
  209. if ($res = _handle_away() ) {
  210. deb("got a response from handle_away");
  211. return($res);
  212. }
  213. // test if "to" is afk
  214. if (! ( $msg = _chatter_is_away($this->to) === false ) ) {
  215. deb("recipient is away");
  216. $res =& _response_to_me( $_SESSION['translator']->out('CHATTER_IS_AWAY'));
  217. $res->line->set_whispered();
  218. $res->comment='msg to '.$this->PlainSender.' that '.$this->PlainRecipient.' is away';
  219. $res->show_local = true;
  220. return($res);
  221. }
  222.  
  223. // test if channel exists
  224. if (! _channel_exists($this->channel) ) {
  225. deb("channel does not exists");
  226. $res =& _response_to_me ( $_SESSION['translator']->out(CHANNEL) . ' '.
  227. $_SESSION['translator']->out(NOT_FOUND) );
  228. $res->comment="$comment channel does not exist, sending errormsg";
  229. return($res);
  230. }
  231.  
  232. // authorized to speak in channel ?
  233. if( ! $_SESSION['chatter']->is_authorized_for( $this->channel )) {
  234. deb("chatter not authorized to speak");
  235. $res =& _response_to_me($_SESSION['translator']->out(NOT). ' '.
  236. $_SESSION['translator']->out(AUTHORIZED));
  237. $res->line->set_whispered();
  238. $res->comment='msg to '.$this->from.' that he is not authorized';
  239. $res->show_local = true;
  240. return($res);
  241. }
  242.  
  243. deb("starting normal processing");
  244.  
  245. $res =& new Response();
  246. $res->line =& new Line ( $_SESSION['chatter'], '' );
  247. $res->line->set_channel($this->channel);
  248.  
  249. $recipient =& new Recipient( $this->to );
  250. $res->line->set_recipient( $recipient );
  251. unset ($recipient);
  252. $res->line->set_whispered( $this->whispered );
  253. $mytmp = $this->what;
  254. $mytmp = escape_html($mytmp);
  255. global $NONO_WORDS;
  256. $mytmp = check_chat( $mytmp, $NONO_WORDS);
  257. $mytmp = html_breaklines($mytmp);
  258. $mytmp = handle_adodb($mytmp);
  259.  
  260. $res->line->set_said($mytmp);
  261. unset($mytmp);
  262. $res->line->filter_buffer_input();
  263. $res->line->set_accepted_mime_types($ACCEPTED_MIME_TYPES);
  264. // check if moderated
  265. $chnl = new Channel($this->channel);
  266. if (! $chnl->is_moderated() ) {
  267. // print line locally and in buffer
  268. $res->show_local = true;
  269. $res->show_remote = true;
  270. $res->comment = "normal line: ".$this->what;
  271. $allres[] = $res;
  272. }
  273. else {
  274. if ( $_SESSION['chatter']->is_vip() || $_SESSION['chatter']->is_moderator() ) {
  275. $res->line->set_approved();
  276. $res->comment = "line from moderator or vip: ".$this->what ;
  277. $res->show_local = true;
  278. $res->show_remote = true;
  279. $allres[] = $res;
  280. }
  281. else {
  282. // we are not moderator nore vip
  283. // first of all, look if a moderator is already present in the channel
  284. $_SESSION['chat']->connect();
  285. $moderators = $_SESSION['chat']->get_group_members("moderator", $this->channel );
  286. $chatters = $_SESSION['chat']->get_chatters($this->channel);
  287. $_SESSION['chat']->disconnect();
  288. $moderators_online = array();
  289. foreach ( $moderators as $mod ) {
  290. if ( in_array($mod, $chatters ) ) {
  291. $moderators_online[] = $mod;
  292. }
  293. }
  294. deb("moderators online: ".print_r($moderators_online,1));
  295. if ( empty($moderators_online ) ) {
  296. // send info msg that no moderator available
  297. unset ($res);
  298. $res =& _response_to_me($_SESSION['translator']->out('MODERATOR_NOT_HERE') );
  299. $res->show_local=true;
  300. $allres[] = $res;
  301. }
  302. else {
  303. // send line to moderator, send infomsg to chatter
  304. $res->comment = "line in moderated channel: ".$this->what;
  305. $res->show_remote = true;
  306. $res->show_local = false;
  307. $allres[] = $res;
  308. unset($res);
  309. $res =& _response_to_me( $_SESSION['translator']->out('MESSAGE_FORWARDED_TO_MODERATOR') );
  310. $res->comment='msg to '.$this->from.' that line is forwarded to moderator';
  311. $res->show_local = true;
  312. $res->show_remote = false;
  313. $res->line->set_whispered();
  314. $allres[] = $res;
  315. }
  316. }
  317. }
  318. unset($chnl);
  319. return($allres);
  320. }
  321. }
  322.  
  323. /**
  324. * Implements the irc-like command "join"
  325. *
  326. * @package phpopenchat
  327. */
  328. class JoinCommand extends Command {
  329. var $channel = '';
  330. var $password = '';
  331.  
  332. function JoinCommand ($channel = '', $password = '') {
  333. if ($channel == '') {
  334. $this->error=NO_CHANNEL_SELECTED;
  335. }
  336. $this->password = $password;
  337. $this->channel=$channel;
  338. }
  339. function run () {
  340. if ( $res = _handle_away() ) {
  341. return($res);
  342. }
  343. deb("entering run join");
  344. $comment = "/join ".$this->channel.":";
  345. if ($this->error || $_SESSION['channel']->get_name() == $this->channel ) {
  346. deb("channel is the same");
  347. // simply return an empty response that does nothing
  348. $res=& _response_to_me('');
  349. $res->comment="$comment no channel selected or channel is the same as before. Do nothing.";
  350. $res->show_local=false;
  351. return($res);
  352. }
  353.  
  354. if ( ! _channel_exists($this->channel) ) {
  355. deb("channel does not exists");
  356. $res =& _response_to_me ( $_SESSION['translator']->out(ERROR_CHANNEL_UPDATE) );
  357. $res->comment="$comment channel does not exist, sending errormsg";
  358. return($res);
  359. }
  360. // maybe password is sent ?
  361. if ($this->password) {
  362. deb("password found:".$this->password);
  363. $chnl =& new Channel($this->channel);
  364. if (! $chnl ) {
  365. die ("new Channel failed. this should never happen!");
  366. }
  367.  
  368. if ( $chnl->get_password() == $this->password ) {
  369. deb("joning channel with password");
  370. $_SESSION['chatter']->unlock_channel($this->channel);
  371. }
  372. else {
  373. deb("implement me: wrong password:".$this->password." for channel ".$this->channel);
  374. }
  375. unset($chnl);
  376. }
  377. if( $_SESSION['chatter']->is_authorized_for( $this->channel )) {
  378. // maybe we require to unlock channel every time user is joining
  379. // then this would lock the channel we are leaving
  380. // /*
  381. deb("yes, im authorized");
  382. if ( $_SESSION['channel']->is_password_protected() ) {
  383. $_SESSION['chatter']->lock_channel($_SESSION['channel']->get_name());
  384. }
  385. // */
  386.  
  387. $_SESSION['reload_count'] = 0; //reset chat session expiration time
  388. $_SESSION['chatter']->join_channel( $this->channel );
  389.  
  390. $res =& _response_to_me('');
  391. $res->comment="$comment succeeded. Channel switched";
  392. $res->show_local=true;
  393. $res->show_remote = false;
  394. }
  395. else {
  396. deb("not authorized");
  397. $res =& _response_to_me('');
  398. $res->show_local=false;
  399. $res->show_remote=false;
  400. $res->set_channel_login(true);
  401. $res->line->set_channel($this->channel);
  402. $res->comment="$comment is locked, display login form";
  403. return($res);
  404. }
  405. return($res);
  406. }
  407. }
  408.  
  409. /**
  410. * Implements the irc-like command "roll"
  411. *
  412. * Roll means the is a dies game where a user can roll dies
  413. *
  414. * @package phpopenchat
  415. */
  416. class RollCommand extends Command {
  417. var $num;
  418. function RollCommand ( $num = 1 ) {
  419. if ( $num == "" ) $num = 1;
  420. if (! is_numeric($num) ) {
  421. $this->error = WRONG_PARAMETER;
  422. }
  423. $num=(integer) $num;
  424. if ($num > 6) $num=6;
  425. $this->num = $num;
  426. }
  427. function run () {
  428. if ( $res = _handle_away() ) {
  429. return($res);
  430. }
  431. $htmlhead = '<img src="'.$_SESSION['template']->get_tmpl_web_path().'/images/icons/dice_';
  432. $htmltail = '.png" align="middle" alt="'.$_SESSION['translator']->out('DIE').'" width="16" height="16" border="0" /> ';
  433. for ($i=1;$i<=$this->num;$i++) {
  434. $html.=$htmlhead.rand(1,6).$htmltail;
  435. }
  436. $response =& new Response();
  437. $response->comment="showing ".$this->num." dices";
  438. $response->show_remote = true;
  439. $response->line =& NewLineFromBot();
  440. $response->line->set_said($html);
  441. $response->line->set_recipient($_SESSION['chatter']);
  442. return($response);
  443. }
  444. }
  445.  
  446. /**
  447. * Implements the irc-like command "show buddy"
  448. *
  449. * @package phpopenchat
  450. */
  451. class ShowbuddyCommand extends Command {
  452. function ShowbuddyCommand () {
  453. }
  454. function run() {
  455. if ( $res = _handle_away() ) {
  456. return($res);
  457. }
  458. $friends = $_SESSION['chatter']->get_friends();
  459. $friends_list = '';
  460. foreach ($friends as $friend) {
  461. $friends_list .= ', '.$friend;
  462. }
  463. unset($friends);
  464. unset($friend);
  465. define('_CHATTER_BUDDY_LIST', substr($friends_list, 2));
  466. unset($friends_list);
  467.  
  468. $res =& new Response();
  469. $res->comment='showing buddies of '.$_SESSION['chatter']->get_nick();
  470. $res->line =& NewLineFromBot();
  471. $res->line->set_whispered();
  472. $res->line->set_recipient($_SESSION['chatter']);
  473. //get template of inline-help
  474. $content = $_SESSION['chat']->get_template('inline_boddies', true);
  475. $res->line->set_said($content);
  476. unset($content);
  477.  
  478. $res->show_local = true;
  479. $res->show_remote = false;
  480. return($res);
  481. }
  482. }
  483.  
  484.  
  485. /**
  486. * Implements the irc-like command "msg"
  487. *
  488. * @package phpopenchat
  489. */
  490. class MsgCommand extends Command {
  491. /* IRC-command
  492. * /msg <nickname> <line content>
  493. * to whisper to a chatter
  494. */
  495. var $nickname = '';
  496. var $content = '';
  497. function MsgCommand ( $nickname = '' , $irc = array() ) {
  498. if ( ! $nickname or ! is_array($irc) ) {
  499. $this->error = WRONG_PARAMETER;
  500. }
  501. $this->nickname = $nickname;
  502. $this->content = implode (" ", $irc);
  503. $this->content = preg_replace('#msg *'.$nickname.' *#', '', $this->content );
  504. }
  505. function run () {
  506. deb("running msg command with params: ".$this->nickname." ".$this->content);
  507.  
  508. if ( $res = _handle_away() ) {
  509. return($res);
  510. }
  511. $_SESSION['chat']->connect();
  512. $recipient_channel = $_SESSION['chat']->get_channel_of($this->nickname);
  513. $_SESSION['chat']->disconnect();
  514.  
  515. if( ! $recipient_channel ) {
  516. $res =& _response_to_me($this->nickname.' '.$_SESSION['translator']->out('IS_NOT_ONLINE'));
  517. $res->comment='displaying a message that chatter is not online';
  518. return($res);
  519. }
  520.  
  521. $allres=array();
  522. // create msg to chatter
  523. $res = _response_to_me($_SESSION['translator']->out('LINE_HAS_BEEN_SENT_TO').' '.
  524. $this->nickname.' '.
  525. '['.$recipient_channel.']'
  526. );
  527. $res->comment="displaying line that line is sent";
  528.  
  529. $allres[] = $res;
  530. unset($res);
  531. $cl =& new _ChatlineCommand ( $_SESSION['chatter']->get_nick(),
  532. $this->nickname,
  533. $recipient_channel,
  534. $this->content,
  535. true ) ;
  536.  
  537. $res = $cl->run();
  538.  
  539. if (is_array($res))
  540. $allres = array_merge($allres, $res );
  541. else
  542. $allres[] = $res;
  543. return($allres);
  544.  
  545. }
  546. }
  547.  
  548.  
  549. /**
  550. * Implements the irc-like command "plain line"
  551. *
  552. * @package phpopenchat
  553. */
  554. class PlainlineCommand extends Command {
  555. // var $line=null;
  556.  
  557.  
  558. var $PlainSender = '';
  559. var $PlainRecipient = '';
  560. var $PlainChannel = '';
  561. var $PlainLine = '';
  562. var $PlainWhispered = 'off';
  563. var $channel_password = '';
  564.  
  565. function PlainlineCommand($icl) {
  566. /* set the recipient. we have two (or three) possibilities:
  567. 1. recipient is set in InputChatline (as part of $_POST)
  568. 2. recipient is set on the textline like "nickname: line" (overrides POST if nick is in chann
  569. el )
  570. 3. recipient is not set at all
  571. */
  572.  
  573. if (! $icl->recipient ) $icl->recipient = '###EVERYBODY###';
  574. preg_match ( '#^([[:alpha:]]+[[:alnum:]]*[^:]*)(: ?)(.*)$#i', $icl->line, $recipient_from_line )
  575. ;
  576. if( count($recipient_from_line) > 0 ) {
  577. if( $line_recipient = $_SESSION['channel']->is_attendant($recipient_from_line[1],true) ) {
  578. $icl->line = str_replace($recipient_from_line[1].$recipient_from_line[2],'',$icl->line );
  579. $icl->recipient = $line_recipient;
  580. }
  581. }
  582. $this->PlainRecipient = $icl->recipient;
  583. $this->PlainSender = $_SESSION['chatter']->get_nick();
  584. $this->PlainLine = $icl->line;
  585.  
  586.  
  587. $this->PlainChannel = $icl->channel ? $icl->channel : CHANNEL_SELECTED ;
  588. $this->PlainWhispered = $icl->whispered ? $icl->whispered : 'off';
  589. $this->channel_password = $icl->channel_password;
  590. }
  591. function run() {
  592. deb("running PlainlineCommand", 'dataflow');
  593. $allres = array(); // array of responses if set
  594. if ( $_SESSION['channel']->get_name() != $this->PlainChannel ) {
  595. $join =& new JoinCommand($this->PlainChannel, $this->channel_password);
  596. $allres[] = $join->run();
  597. unset ($join);
  598. }
  599. $cmd =& new _ChatlineCommand($this->PlainSender, $this->PlainRecipient, $this->PlainChannel,
  600. $this->PlainLine,
  601. $this->PlainWhispered == 'on' ?