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,"