name)] = $funcname; if ($i->status < 3) $this->binds_cleanup['on_connect'] = register_callback('on_connect',array(&$this,'introduce')); else $this->introduce($i); if ($i->status == 4) $this->self_autojoin($i); else $this->binds_cleanup['on_eos'] = register_callback('on_eos',array(&$this, 'self_autojoin')); $i->privmsg['x'] = array(&$this, 'privmsg'); $timer_obj['is'] =& $this; } function __destruct() { global $binds, $users, $i, $timer_obj; if (ake(strtolower($this->me->nick),$users)) { $i->send(':'.$users[strtolower($this->me->nick)]->nick.' , :Module unloaded'); unset($users[strtolower($this->me->nick)]); } unset ($i->privmsg['x']); unset ($timer_obj['is']); unset($ci); foreach ($this->binds_cleanup as $bindname => $key) unregister_callback($bindname, $key); } function introduce(&$i) { $me =& $this->me; $me = new user; $me->handler = array('chanmsg_parser' => array(&$this, 'chanmsg_parser')); $me->nick = 'X'; $me->host = 'nix.co.il'; $me->username = 'service'; $me->modes->apply('+Sqrz'); $me->server =& $i->me; $i->me->users[] =& $me; global $users; $users[strtolower($me->nick)] =& $me; $i->send('& '.$me->nick.' 1 !'.$i->to_base64($this->me->my_signon).' '.$me->username.' '.$me->host.' '.$me->server->name.' 0 +Sqz * * :Information Service'); $this->source = $me->nick; //.'!'.$me->username.'@'.$me->host; } function privmsg(&$i,$source,$target,$message) { global $users, $channels, $hs, $ci; $command = strtoupper(firstword($message,$parameters)); if (!ake(strtolower($source),$users)) { errlog($this->name,"User $source not found!"); return; } $u =& $users[strtolower($source)]; if (!$u or !$u->ngi or (ake('NS_SECURE',$u->ngi->flags) and $u->ngi->status < 10) or $u->ngi->status < 5) { $hs->helpnotice($u,$this->source,'NICK_IDENTIFY_REQUIRED','c',$command); return; } $cmd = 'privmsg_'.strtolower($command); if (!is_callable(array(&$this,$cmd))) { $hs->helpnotice($u,$this->source,'UNKNOWN_COMMAND','c',$command); return; } switch ($this->{$cmd}($i, $u, $u->ngi->access, $parameters)) { case 1: $hs->helpnotice($u,$this->source,'ACCESS_DENIED'); break; case 2: $hs->helpnotice($u,$this->source,'BAD_SYNTAX','c',$command); $hs->helpnotice($u,$this->source,'MORE_INFO','s',$this->name,'p',$command); break; case 3: $hs->helpnotice($u,$this->source,'INTERNAL_ERROR'); errlog($this->name.':'.$command,'INTERNAL_ERROR'); break; case 4: $hs->helpnotice($u,$this->source,'MISSING_QUOTE'); break; case 5: $hs->helpnotice($u,$this->source,'READ_ONLY_MODE'); errlog($this->name.':'.$command,'READ_ONLY_MODE'); break; case 6: $hs->helpnotice($u,$this->source,'SENDMAIL_NO_RESOURCES'); errlog($this->name.':'.$command,'SENDMAIL_NO_RESOURCES'); break; case 7: $hs->helpnotice($u,$this->source,'SERVICES_IS_BUSY'); errlog($this->name.':'.$command,'SERVICES_IS_BUSY'); break; } last_corruptor_check($u,$this); } function privmsg_yahoo (&$i,&$u,$access,$pars) { return 3; include_once 'Zend/Service/Yahoo.php'; if (!class_exists('Zend_Service_Yahoo')) return 3; $yahoo = new Zend_Service_Yahoo("nix_irc_network"); $results = $yahoo->webSearch($pars); foreach ($results as $r) { $i->send(":$this->source B {$u->nick} :Yahoo! $r->Title $r->Url"); break; } } function privmsg_join (irc_connection &$i,user &$u,$access,$pars) { if ($access < XS_SUPER) return 1; $chan = firstword($pars,$pars); $c =& $this->self_parsechan($chan); if (!is_object($c)) { global $hs; $hs->helpnotice($u,$this->source,'CHAN_X_NOT_IN_USE','s',$chan); return; } $this->self_join($i, $c); } function privmsg_subscribe (irc_connection &$i,user &$u,$access,$pars) { global $hs, $cs; $chan = firstword($pars,$pars); $c =& $this->self_parsechan($chan); if (!$c) return $hs->helpnotice($u,$this->source,'CHAN_X_NOT_IN_USE','s',$chan); if (!$c->ci) return $hs->helpnotice($u,$this->source,'CHAN_X_NOT_REGISTERED','s',$c->name); if (!$cs) return 3; if ($u->ngi->access < XS_OPER and (is_null($c->ci->levels->set) or $c->ci->levels->set > $cs->get_status($c, $u))) return 1; q("INSERT INTO is_subscr SET cid = {$c->ci->cid};"); if (!mysql_affected_rows()) return $hs->$hs->helpnotice($u,$this->source,'INFO_SUBSCRIBE_FAILED','c',$c->name,'x',$this->name); $this->self_join($i, $c); $hs->helpnotice($u,$this->source,'INFO_SUBSCRIBE_SUCCESS','c',$c->name,'x',$this->name); } function privmsg_unsubscribe (irc_connection &$i,user &$u,$access,$pars) { global $hs, $cs; $chan = firstword($pars,$pars); $c =& $this->self_parsechan($chan); if (!$c) return $hs->helpnotice($u,$this->source,'CHAN_X_NOT_IN_USE','s',$chan); if (!$c->ci) return $hs->helpnotice($u,$this->source,'CHAN_X_NOT_REGISTERED','s',$c->name); if (!$cs) return 3; if ($u->ngi->access < XS_OPER and (is_null($c->ci->levels->set) or $c->ci->levels->set > $cs->get_status($c, $u))) return 1; q("DELETE FROM is_subscr WHERE cid = {$c->ci->cid};"); if (!mysql_affected_rows()) return $hs->$hs->helpnotice($u,$this->source,'INFO_UNSUBSCRIBE_FAILED','c',$c->name,'x',$this->name); if (ake(strtolower($this->me->nick),$c->userlist)) { $send = ":{$this->me->nick} PART $c->name :Unsubscribed by $u->nick"; $i->send($send); $i->parse($send); } $hs->helpnotice($u,$this->source,'INFO_UNSUBSCRIBE_SUCCESS','c',$c->name,'x',$this->name); } function self_join (irc_connection &$i, channel &$c) { if (!is_object($c)) return; if (ake(strtolower($this->me->nick),$c->userlist)) return; $send = "~ !".$i->to_base64($c->creation_time)." {$c->name} :{$this->me->nick}"; //+a before : ? $i->send($send); $i->parse(':'.name.' '.$send); } function self_parsechan($chan) { global $channels; if (!ake(strtolower($chan),$channels)) return null; else return $channels[strtolower($chan)]; } function self_autojoin(irc_connection &$i) { $r = q("SELECT name FROM cs_chan, is_subscr WHERE cs_chan.cid = is_subscr.cid"); while($chan = fs($r) and $chan) { $c =& $this->self_parsechan($chan); if (!$c) continue; $this->self_join($i, $c); } } function self_output(irc_connection &$i, channel &$c, user &$u, $text) { if ($c->ci and ake('CS_UTF8',$c->ci->flags)) { if (!is_hebrew_utf8($text)) { $text = iconv('cp1255', 'utf8', $text); } } else { $text = iconv_('utf8','cp1255',$text); } $i->send(":{$this->source} ! $c->name :{$u->nick}: $text"); } function chanmsg_parser(irc_connection &$i, $source, $target, $message) { if ($message{0} != '!') return; global $users; if (!ake(strtolower($source),$users)) return; $u =& $users[strtolower($source)]; if (!$u) return; if (!is_object($u->ngi)) { if (!ake($source,$this->naglist)) $i->send(":{$this->source} ! $source :Hi, I'm a bot. If you want to use my features please register! /ns help register"); return; } $c =& $this->self_parsechan($target); if (!$c) return; $command = firstword($message, $message); $message = substr($message,0,100); switch (strtolower($command)) { case '!g': case '!g1': case '!google': $command = 'google_search'; /*$pid = pcntl_fork(); if ($pid == -1) { errlog("InfoServ/ChanParser","Failed to fork"); } if (!$pid) { $results = $this->google_pda($message); if (!count($results)) { $this->self_output($i, $c, $u, "Sorry, Google didn't find anything."); return; } foreach ($results as $r) { $search = array('','',"\n","\r"); $replace = array(chr(2), chr(2),"",""); $result = html_entity_decode(str_replace($search,$replace,$r[1]))." ".chr(31).$r[0].chr(31); $this->self_output($i, $c, $u, $result); break; } $this->google_last[$u->nick] = array($message, 1); exit; } return;*/ break; case '!g2': case '!g3': case '!g4': $command = 'google_search_show'.$command{2}; break; case '!gg': case '!gn': case '!gnext': case '!googlenext': $command = 'google_search_next'; break; case '!y': case '!yahoo': $command = 'yahoo_search'; break; case '!translate': case '!t': $command = 'morfix'; $message = firstword($message); break; case '!seen': global $ng, $ns, $hs; $target = firstword($message); if (!$ns->valid_nick($target)) $msg = "Sorry, please be more specific"; elseif (!ake(strtolower($target),$ng)) $msg = "Err, I only track registered users"; else { $ngi =& $ng[strtolower($target)]->ngi; $target = $ng[strtolower($target)]->nick; $tu = NULL; foreach ($ngi->nicks as &$nick) { if (ake(strtolower($nick->nick),$users)) { $tu =& $users[strtolower($nick->nick)]; break; } } if ($tu instanceof user) { if ($u->ngi->ngi == $ngi->ngi) { $msg = "Having identity issues?"; } elseif (ake(strtolower($c->name),$tu->channels)) { if (is_array($tu->away)) { $msg = "$target is away for ". $hs->duration_short(time() - $tu->away['time'],$u->lang,false); } else { $msg = "$target is right here"; } $msg .= (abs(strcasecmp($target,$tu->nick)) ? ", he is called $tu->nick" : '' ); } else { $tc = NULL; //target channel $oc = NULL; //other channel $secret = false; foreach ($tu->channels as &$chan) { if (ake($u->lnick(),$chan->userlist)) { if ($chan->modes->ls or $chan->modes->lp) { $secret = true; continue; } $tc =& $chan; break; } elseif ($chan->modes->ls or $chan->modes->lp) { continue; } elseif (!$oc) { $oc =& $chan; } } if (!$tc) $tc =& $oc; if (!$tc) { if ($secret) { $msg = "$target is with you in a private channel"; } else { $msg = "$target is online but I can't really say where"; } } else { $msg = "You can catch $target over at $tc->name"; } } } else { if ($ngi->last_quit_time >= $ngi->last_seen) { $msg = "$target has left " .$hs->duration_short(time() - $ngi->last_quit_time,$u->lang,true) ." ($ngi->last_quit)"; } else { $msg = "$target has last been seen " .$hs->duration_short(time() - $ngi->last_seen,$u->lang,true); } global $ms; } } $this->self_output($i, $c, $u, $msg); break; default: return; } run_at(0,'is chanmsg_postparser_catcher',serialize(array($u->nick,$c->name,strtolower($command),$message))); } function chanmsg_postparser(irc_connection &$i, user &$u, channel &$c, $command, $message) { switch ($command) { case 'yahoo_search': return; include_once 'Zend/Service/Yahoo.php'; if (!class_exists('Zend_Service_Yahoo')) return 3; $yahoo = new Zend_Service_Yahoo("nix_irc_network"); $results = $yahoo->webSearch($message); foreach ($results as $r) { $this->self_output($i, $c, $u, "$r->Title $r->Url"); break; } break; case 'google_search': $results = $this->google_pda($message); if (!count($results)) { $this->self_output($i, $c, $u, "Sorry, Google didn't find anything."); return; } foreach ($results as $r) { $search = array('','',"\n","\r"); $replace = array(chr(2), chr(2),"",""); $result = html_entity_decode(str_replace($search,$replace,$r[1]))." ".chr(31).$r[0].chr(31); $this->self_output($i, $c, $u, $result); break; } $this->google_last[$u->nick] = array($message, 1); break; case 'google_search_show2': case 'google_search_show3': case 'google_search_show4': $results = $this->google_pda($message); if (!count($results)) { $this->self_output($i, $c, $u, "Sorry, Google didn't find anything."); return; } $count = (int)$command{18}; $this->google_last[$u->nick] = array($message, $count); $x = 1; foreach ($results as $r) { $search = array('','',"\n","\r"); $replace = array(chr(2), chr(2),"",""); $result = html_entity_decode(str_replace($search,$replace,$r[1]))." ".chr(31).$r[0].chr(31); $this->self_output($i, $c, $u, "{$x}. ".$result); if ($x++ == $count) break; } break; case 'google_search_next': if (!array_key_exists($u->nick,$this->google_history) and $message) { $this->google_last[$u->nick] = array($message, 0); } $results = $this->google_pda($this->google_last[$u->nick][0]); if (!count($results)) { $this->self_output($i, $c, $u, "Sorry, Google didn't find anything."); return; } $x = 1; ++$this->google_last[$u->nick][1]; foreach ($results as $r) { if (isset($this->google_history[$u->nick]) and is_int($this->google_history[$u->nick])) continue; if (ake($u->nick,$this->google_last) and $x < $this->google_last[$u->nick][1]) { ++$x; continue; } $search = array('','',"\n","\r"); $replace = array(chr(2), chr(2),"",""); $result = html_entity_decode(str_replace($search,$replace,$r[1]))." ".chr(31).$r[0].chr(31); $this->self_output($i, $c, $u, "{$x}. ".$result); if ($x++ >= $this->google_last[$u->nick][1]) break; } break; case 'morfix': $message = iconv_('utf8','cp1255',$message); /*if (ake(strtolower($message),$this->morfix_history)) { $o =& $this->morfix_history[strtolower($message)]; $lang = $o[1]; if (!$o[0]) { $results = array(); $suggest = $o[2]; } else { $results = $o[2]; } } else*/ $r = fs(q("SELECT `result` FROM `is_morfix` WHERE `query` = '" .es(strtolower($message))."' LIMIT 1")); if ($r) { $o = unserialize(bzdecompress($r)); $lang = $o[1]; if (!$o[0]) { $results = array(); $suggest = $o[2]; } else { $results = $o[2]; } } else { $lang = (preg_match("/([\xE0-\xFA])/",$message) ? 'he' : 'en'); if ($lang == 'en') $this->self_output($i, $c, $u, "Off I go, I should be back soon."); elseif ($lang == 'he') $this->self_output($i, $c, $u, "אני זז לחפש, לוקח לי שנים אני יודע."); $uri = "http://milon.morfix.co.il/Default.aspx?q=".urlencode($message); $opts = array( 'http' => array( 'method'=>"GET", 'header'=>"Accept-language: en\r\n" ), 'socket' => array( 'bindto' => '80.179.149.48:0' ) ); $context = stream_context_create($opts); $morfix_content = file_get_contents($uri, false, $context); $pos = strpos($morfix_content, "class='cTitleStrip'><"); $pos = strpos($morfix_content, "onclick=\"ToSearch("); $poslow = $pos; $results = array(); while ($pos !== false and $pos >= $poslow) { $pos = strpos($morfix_content, "", $pos) + 1; $posend = strpos($morfix_content, "<", $pos); $word = substr($morfix_content, $pos, $posend - $pos); $pos = strpos($morfix_content, "", $pos) + 1; $posend = strpos($morfix_content, "<", $pos); $type = substr($morfix_content, $pos, $posend - $pos); $pos = strpos($morfix_content, "", $pos) + 1; $posend = strpos($morfix_content, "<", $pos); $meaning = substr($morfix_content, $pos, $posend - $pos); $results[] = array($word, $type, $meaning); $pos = strpos($morfix_content, "onclick=\"ToSearch(", $posend); }; $o = array(); if (empty($results)) { preg_match_all("/SubmitSuggest\('([^']+)'\)/",$morfix_content,$suggest); unset($suggest[0]); $suggest = $suggest[1]; $o[0] = false; $o[2] = $suggest; } else { $o[0] = true; $o[2] = $results; } $o[1] = $lang; q("INSERT INTO `is_morfix` SET `query`='" .es(strtolower($message))."', `result`='" .es(bzcompress(serialize($o)))."';",true); } if (empty($results) and !empty($suggest)) { if (count($suggest) > 1) { if ($lang == 'en') $this->self_output($i, $c, $u, "No matches found, maybe you meant one of the following:"); elseif ($lang == 'he') $this->self_output($i, $c, $u, "לא מצאתי את מה שחיפשת, אולי זה אחד הדברים הבאים:"); $i->send(":{$this->source} ! $c->name :{$u->nick}: ".implode(', ',$suggest)); } else { if ($lang == 'en') $this->self_output($i, $c, $u, "No matches found, maybe you meant ".chr(2).$suggest[0].chr(2)."?"); elseif ($lang == 'he') $this->self_output($i, $c, $u, "לא מצאתי את מה שחיפשת, אולי התכוונת ל".$suggest[0]."?"); } } elseif (!empty($results)) { foreach ($results as $result) { $this->self_output($i, $c, $u, chr(2)."$result[0]".chr(2)." ({$result[1]}) $result[2]"); } } else { if ($lang == 'en') $this->self_output($i, $c, $u, "No matches found, no suggestions either."); elseif ($lang == 'he') $this->self_output($i, $c, $u, "לא מצאתי את מה שרצית, גם אין לי הצעות."); } break; } } function google_pda ($query) { if (array_key_exists($query,$this->google_history) and $this->google_history[$query][-1] + 3600 > time()) { return $this->google_history[$query]; } $uri = "http://www.google.co.il/pda/search?lr=&hl=en&mrestrict=xhtml&q=". urlencode(iconv_('cp1255','utf8',$query))."&btnG=Search&site=search"; $opts = array( 'http' => array( 'method'=>"GET", 'header'=>"Accept-language: en\r\n" ), 'socket' => array( 'bindto' => '80.179.149.50:0' ) ); $context = stream_context_create($opts); $google_content = file_get_contents($uri, false, $context); $res = array(); $k = strpos($google_content,"", $k); $con = substr($google_content, $k, $j - $k); $res[] = array($url, $con); $k = $j + 1; $k = strpos($google_content,"