All pastes #427067 Raw Edit

Someone

public text v1 · immutable
·published 2007-04-06 16:22 UTC
rendered paste body
<?php
class InfoServ___ {
	public $name = 'X', $source;
	protected $me, $binds_cleanup = array();
	protected $naglist = array(), $google_history = array(), $google_last = array();
	protected $morfix_history = array();
	function __construct() {
		global $binds, $i, $timer_obj, $unload_module;
		$funcname = create_function('','global $is; unset($is);');
		$unload_module[strtolower($this->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('<b>','</b>',"\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('<b>','</b>',"\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('<b>','</b>',"\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('<b>','</b>',"\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, "&#1488;&#1504;&#1497; &#1494;&#1494; &#1500;&#1495;&#1508;&#1513;, &#1500;&#1493;&#1511;&#1495; &#1500;&#1497; &#1513;&#1504;&#1497;&#1501; &#1488;&#1504;&#1497; &#1497;&#1493;&#1491;&#1506;.");
					$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, "<span ", $pos);
						$pos = strpos($morfix_content, ">", $pos) + 1;
						$posend = strpos($morfix_content, "<", $pos);
						$word = substr($morfix_content, $pos, $posend - $pos);
						$pos = strpos($morfix_content, "<span ", $posend);
						$pos = strpos($morfix_content, ">", $pos) + 1;
						$posend = strpos($morfix_content, "<", $pos);
						$type = substr($morfix_content, $pos, $posend - $pos);
						$pos = strpos($morfix_content, "<span ", $posend);
						$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, "&#1500;&#1488; &#1502;&#1510;&#1488;&#1514;&#1497; &#1488;&#1514; &#1502;&#1492; &#1513;&#1495;&#1497;&#1508;&#1513;&#1514;, &#1488;&#1493;&#1500;&#1497; &#1494;&#1492; &#1488;&#1495;&#1491; &#1492;&#1491;&#1489;&#1512;&#1497;&#1501; &#1492;&#1489;&#1488;&#1497;&#1501;:");
						$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, "&#1500;&#1488; &#1502;&#1510;&#1488;&#1514;&#1497; &#1488;&#1514; &#1502;&#1492; &#1513;&#1495;&#1497;&#1508;&#1513;&#1514;, &#1488;&#1493;&#1500;&#1497; &#1492;&#1514;&#1499;&#1493;&#1493;&#1504;&#1514; &#1500;".$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, "&#1500;&#1488; &#1502;&#1510;&#1488;&#1514;&#1497; &#1488;&#1514; &#1502;&#1492; &#1513;&#1512;&#1510;&#1497;&#1514;, &#1490;&#1501; &#1488;&#1497;&#1503; &#1500;&#1497; &#1492;&#1510;&#1506;&#1493;&#1514;.");
				}
				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,"</b><a accesskey=");
		while ($k !== false) {
			$k = strpos($google_content, 'href="', $k) + 6;
			$j = strpos($google_content, '"', $k);
			$url = substr($google_content, $k, $j - $k);
			$k = $j + 3;
			$j = strpos($google_content, "</a>", $k);
			$con = substr($google_content, $k, $j - $k);
			$res[] = array($url, $con);
			$k = $j + 1;
			$k = strpos($google_content,"</b><a accesskey=", $k);
		}
		unset($google_content);
		$this->google_history[$query] = $res;
		$this->google_history[$query][-1] = time();
		return $res;
	}
	function chanmsg_postparser_catcher($serialized) {
		//TODO make it a simpler timer-to-object transition
		global $i, $users;
		list($source,$target,$command,$message) = unserialize($serialized);
		if (!ake(strtolower($source),$users)) return;
		$u =& $users[strtolower($source)];
		if (!$u) return;
		$c =& $this->self_parsechan($target);
		if (!$c) return;
		$this->chanmsg_postparser($i, $u, $c, $command, $message);
	}
}
global $is;
$is = new InfoServ___();
?>