<?php
/*
+---------------------------------------------------------------------------
| PHP-IRC v2.2.1 Service Release
| ========================================================
| by Manick
| (c) 2001-2005 by http://www.phpbots.org/
| Contact: manick@manekian.com
| irc: #manekian@irc.rizon.net
| ========================================
+---------------------------------------------------------------------------
| > parser module
| > Module written by Manick
| > Module Version Number: 2.2.0
+---------------------------------------------------------------------------
| > This program is free software; you can redistribute it and/or
| > modify it under the terms of the GNU General Public License
| > as published by the Free Software Foundation; either version 2
| > of the License, or (at your option) any later version.
| >
| > This program is distributed in the hope that it will be useful,
| > but WITHOUT ANY WARRANTY; without even the implied warranty of
| > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| > GNU General Public License for more details.
| >
| > You should have received a copy of the GNU General Public License
| > along with this program; if not, write to the Free Software
| > Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+---------------------------------------------------------------------------
| Changes
| =======-------
| > If you wish to suggest or submit an update/change to the source
| > code, email me at manick@manekian.com with the change, and I
| > will look to adding it in as soon as I can.
+---------------------------------------------------------------------------
*/
class parser {
private $cmd;
private $args;
private $timers =
array();
private $cmdList =
array();
private $cmdTypes =
array();
private $fileModified =
array();
private $loadDefError = false;
//Classes
private $ircClass;
private $dccClass;
private $timerClass;
private $socketClass;
private $db;
/* Part of easy alias idea I've been working on..., look below for large bit of commented out code
for info...
private $aliasArray = array( "notice" => "ircClass",
"privMsg" => "ircClass",
"action" => "ircClass",
"sendRaw" => "ircClass",
"getNick" => "ircClass",
"isOnline" => "ircClass",
"isMode" => "ircClass",
"isChanMode" => "ircClass",
"sendFile" => "dccClass",
"dccInform" => "dccClass",
"addTimer" => "timerClass",
"addListener" => "socketClass",
"removeTimer" => "timerClass",
);
*/
public function __construct() {
$this->
fileModified =
array();
}
public function init()
{
if ($this->ircClass->getClientConf('functionfile') != "")
{
$this->loadFuncs($this->ircClass->getClientConf('functionfile'));
}
}
public function setDccClass($class)
{
$this->dccClass = $class;
}
public function setIrcClass($class)
{
$this->ircClass = $class;
}
public function setTimerClass($class)
{
$this->timerClass = $class;
}
public function setSocketClass($class)
{
$this->socketClass = $class;
}
public function setDatabase($class)
{
$this->db = $class;
}
public function getCmdList($type = "")
{
if ($type == "")
{
return $this->cmdList;
}
else
{
if (isset($this->
cmdList[$type])) {
return $this->cmdList[$type];
}
else
{
return false;
}
}
}
public function destroyModules()
{
{
if (isset($this->
cmdList['file']) &&
is_array($this->
cmdList['file'])) {
foreach ($this->cmdList['file'] AS $index => $data)
{
{
$data['class']->destroy();
}
}
}
}
}
{
if ($configRaw === false)
{
if (DEBUG == 1)
{
echo "Could not find function file '$file' or error.\n";
}
$this->dccClass->dccInform("Could not find function file '$file' or error.");
return false;
}
return $configRaw;
}
public function include_recurse($file)
{
$configRaw = $this->readFile($file);
if ($configRaw === false)
{
return false;
}
$configRaw =
trim($configRaw);
$lines =
explode("\n",
$configRaw);
$num = 0;
$lineNo = 1;
$extra = 0;
$fullLine = "";
foreach ($lines as $line)
{
if ($line == "")
{
$lineNo++;
continue;
}
$line =
trim($fullLine .
" " .
$line);
$newLine = $this->parseFunc($file, $lineNo, $line);
$lineNo += $extra + 1;
$extra = 0;
$fullLine = "";
if ($newLine === false)
{
continue;
}
if ($newLine['type'] == "type")
{
$this->
cmdTypes[$newLine['typeArray']['name']]['numArgs'] =
count($newLine['typeArray']);
$this->cmdTypes[$newLine['typeArray']['name']]['args'] = $newLine['typeArray'];
}
else if ($newLine['type'] == "include")
{
if (isset($newLine['typeArray'][0])) {
$num += $this->include_recurse($newLine['typeArray'][0]);
}
else
{
if (DEBUG == 1)
{
echo "Malformed include line on line " .
$lineNo .
" of function file: " .
$file .
"\n";
}
$this->dccClass->dccInform("Malformed include line on line " . $lineNo . " of function file: " . $file);
}
}
else
{
if (!
isset($newLine['typeArray']['name'])) {
$name = irc::
randomHash() .
"_" .
rand(1,
1024);
}
else
{
$name = $newLine['typeArray']['name'];
}
unset($newLine['typeArray']['name']);
$this->cmdList[$newLine['type']][$name] = $newLine['typeArray'];
if (isset($this->
cmdList[$newLine['type']][$name]['usage'])) {
if (isset($oldCmdList[$newLine['type']][$name]['usage'])) {
$this->cmdList[$newLine['type']][$name]['usage'] = $oldCmdList[$newLine['type']][$name]['usage'];
}
}
}
$num++;
}
return $num;
}
public function loadFuncs($file)
{
$error = false;
$this->destroyModules();
$oldCmdList = $this->cmdList;
{
}
$this->
cmdList =
array();
$this->
cmdTypes =
array();
$this->dccClass->dccInform("Rehashing Function File, please wait...");
if (DEBUG == 1)
{
echo "Rehashing Function File, please wait...\n";
}
//Read in main function file
$num = $this->include_recurse($file);
//Book keeping
foreach ($this->cmdList AS $cmd => $data)
{
ksort($this->
cmdList[$cmd]);
}
if (isset($this->
cmdList['file'])) {
foreach ($this->cmdList['file'] AS $file => $data)
{
$classDef = $this->loadClassDef($data['filename'], $file);
if ($this->loadDefError == true)
{
$error = true;
}
$this->loadDefError = false;
if ($classDef === false)
{
continue;
}
//require_once($data['filename']);
$this->cmdList['file'][$file]['class'] = new $classDef;
$this->cmdList['file'][$file]['class']->__setClasses( $this->ircClass,
$this->dccClass,
$this->timerClass,
$this,
$this->socketClass,
$this->db
);
$this->cmdList['file'][$file]['class']->init();
}
}
$this->dccClass->dccInform("Successfully loaded " . $num . " functions into memory.");
if (DEBUG == 1)
{
echo "Successfully loaded " .
$num .
" functions into memory.\n";
}
return $error;
}
private function loadClassError($filename, $msg)
{
$this->ircClass->log("Error loading $filename: $msg");
$this->dccClass->dccInform("Error loading $filename: $msg");
}
/* Okay..
* This method is really freaking cool. It loads a module file with fopen, then
* it finds the classname, and gives it a random name (changes it) so that you can
* include functions you've changed multiple times without having to restart the bot!
* Also, easier names than having to use $this->ircClass->blah() all the time, you can
* just use blah()... These are defined in an array somewhere... I'm not sure where yet...
* because I haven't written that yet!!!!!!!!!!!!111oneone.
*/
private function loadClassDef($filename, $classname)
{
if ($stat === false)
{
$this->loadClassError($filename, "Could not find function file");
return false;
}
$modified = $stat['mtime'];
if (isset($this->
fileModified[$filename])) {
if ($modified == $this->fileModified[$filename]['modified'])
{
return $this->fileModified[$filename]['classdef'];
}
}
if ($fileData === false)
{
$this->loadClassError($filename, "Could not find function file");
return false;
}
//Okay, we have the module now.. now we need to find some stuff.
if (!
preg_match("/class[\s]+?".
$classname.
"[\s]+?extends[\s]+?module[\s]+?{/",
$fileData)) {
$this->loadClassError($filename, "Could not find valid classdef in function file");
return false;
}
//Okay, our module is in the file... replace it with random hash.
$newHash = irc::randomHash();
$newClassDef = $classname . "_" . $newHash;
$fileData =
preg_replace("/(class[\s]+?)".
$classname.
"([\s]+?extends[\s]+?module[\s]+?{)/",
"\\1" .
$newClassDef .
"\\2",
$fileData);
/* Interesting idea, but lets leave it out for now
foreach($this->aliasArray AS $func => $class)
{
$fileData = preg_replace("/([=\n\(\t\s]+?)".$func."[\s\t\n\r]*?\(/s", "\\1\$this->" . $class . "->" . $func . "(", $fileData);
}
*/
$success =
eval("?>" .
$fileData .
"<?php ");
if ($success === false)
{
$this->loadClassError($filename, "Error in function file");
/* Attempt to fallback on a previous revision that worked! */
if (isset($this->
fileModified[$filename])) {
$this->loadClassError($filename, "Using a cached version of the class definition");
$this->loadDefError = true;
return $this->fileModified[$filename]['classdef'];
}
return false;
}
$this->fileModified[$filename]['modified'] = $modified;
$this->fileModified[$filename]['classdef'] = $newClassDef;
return $newClassDef;
}
//Used to show array, as there seems to be some crazy bug in var_dump/print_r that
//shows EVERY variable in my program when I do var_dump($this->cmdList) or use print_r the same way
//This isn't used anywhere in the production copy of this script. (DEBUG ONLY!)
private function show_all($title, $array, $level)
{
echo $title .
" = array(" .
"\r\n";
foreach($array AS $index => $val)
{
for ($i = 0; $i < $level; $i++)
{
}
{
$this->show_all($index, $val, $level + 1);
}
{
echo "[$index] => [object]\r\n";
}
else
{
echo "[$index] => [$val]\r\n";
}
}
for ($i = 0; $i < $level; $i++)
{
}
}
public function setCmdListValue($type, $cmd, $var, $value)
{
if (isset($this->
cmdList[$type][$cmd][$var])) {
$this->cmdList[$type][$cmd][$var] = $value;
return true;
}
return false;
}
private function parseFunc($file, $lineNo, $line)
{
$quotes =
array("'",
"\"");
foreach($quotes AS $quote)
{
$currPos = 0;
$extraPos = 0;
while (($firstPos =
strpos($line,
$quote,
$currPos)) !==
false &&
substr($line,
strpos($line,
$quote,
$currPos)-1,
1) !=
"\\") {
while (($secondPos =
strpos($line,
$quote,
$firstPos +
1 +
$extraPos)) !==
false &&
substr($line,
strpos($line,
$quote,
$firstPos +
1 +
$extraPos)-1,
1) ==
"\\") {
$extraPos = $secondPos;
}
if ($secondPos === false)
{
if (DEBUG == 1)
{
echo "Syntax Error on line " .
$lineNo .
" of function file: " .
$file .
". Expected '".
$quote.
"', got end of line.\n";
}
$this->dccClass->dccInform("Syntax Error on line " . $lineNo . " of function file: " . $file . ". Expected '".$quote."', got end of line.");
return false;
}
$strings[$quote][] =
substr($line,
$firstPos +
1,
$secondPos -
$firstPos -
1);
$currPos = $secondPos + 1;
}
}
foreach ($strings AS $string)
{
}
$type = "";
$currElement = 0;
foreach($lineElements AS $element)
{
if (trim($element) ==
"") {
continue;
}
$currElement++;
if ($currElement == 1)
{
$element = irc::myStrToLower($element);
if ($element == "type")
{
$type = "type";
}
else if ($element == "include")
{
$type = "include";
}
else
{
if (isset($this->
cmdTypes[$element])) {
$type = $element;
}
else
{
if (DEBUG == 1)
{
echo "Error: Undefined type, '" .
$element .
"' on line " .
$lineNo .
" of function file: " .
$file .
"\n";
}
$this->dccClass->dccInform("Error: Undefined type, '" . $element . "' on line " . $lineNo . " of function file: " . $file . "");
return false;
}
}
continue;
}
if ($element == "\"\"")
{
}
else if ($element == "''")
{
}
if ($type == "type")
{
if ($currElement == 2)
{
$typeArray['name'] = $element;
}
else
{
$typeArray[] = $element;
}
}
else if ($type == "include")
{
$typeArray[] = $element;
}
else
{
if ($currElement > $this->cmdTypes[$type]['numArgs'])
{
if (DEBUG == 1)
{
echo "Error on line " .
$lineNo .
" of function file: " .
$file .
", too many arguments\n";
}
$this->dccClass->dccInform("Error on line " . $lineNo . " of function file: " . $file . ", too many arguments");
return false;
}
$element = (irc::myStrToLower($element) == "true" ? true : $element);
$element = (irc::myStrToLower($element) == "false" ? false : $element);
$typeArray[$this->cmdTypes[$type]['args'][ $currElement - 2 ]] = $element;
}
}
if ($type != "type" && $type != "include")
{
if ($currElement < $this->cmdTypes[$type]['numArgs'])
{
if (DEBUG == 1)
{
echo "Error on line " .
$lineNo .
" of function file: " .
$file .
", not enough arguments\n";
}
$this->dccClass->dccInform("Error on line " . $lineNo . " of function file: " . $file . ", not enough arguments");
return false;
}
}
return array('type' =>
$type,
'typeArray' =>
$typeArray);
}
public function parseDcc($chat, $handler)
{
$chat->
readQueue =
str_replace("\r",
"",
$chat->
readQueue);
// if (!($offSet = strpos($chat->readQueue, "\n")))
// {
// return false;
// }
// $rawLine = trim(substr($chat->readQueue, 0, $offSet));
// $chat->readQueue = substr($chat->readQueue, $offSet + 1);
$rawLine = $chat->readQueue;
$chat->readQueue = "";
$this->ircClass->log("DCC Chat(" . $chat->nick . "): " . $rawLine);
$line = $this->createLine($rawLine);
if ($line == false)
{
return;
}
if ($handler != false)
{
{
$handler->handle($chat, $line);
return;
}
}
if ($chat->isAdmin == true && $chat->verified == false)
{
if (md5($line['cmd']) ==
$this->
ircClass->
getClientConf('dccadminpass')) {
$this->dccClass->dccInform("DCC: " . $chat->nick . " has successfully logged in.");
$chat->verified = true;
$chat->dccSend("You have successfully logged in.");
}
else
{
$chat->dccSend("Invalid password, bye bye.");
$this->dccClass->disconnect($chat);
}
return;
}
$cmdLower = irc::myStrToLower($line['cmd']);
if (isset($this->
cmdList['dcc'][$cmdLower])) {
if ($this->cmdList['dcc'][$cmdLower]['admin'] == 1 && !$chat->isAdmin)
{
$chat->dccSend("Request Denied. You must have admin access to use this function.");
return;
}
if ($line['nargs'] < $this->cmdList['dcc'][$cmdLower]['numArgs'])
{
$chat->dccSend("Usage: " . $cmdLower . " " . $this->cmdList['dcc'][$cmdLower]['usage']);
return;
}
$module = $this->cmdList['dcc'][$cmdLower]['module'];
$class = $this->cmdList['file'][$module]['class'];
$func = $this->cmdList['dcc'][$cmdLower]['function'];
$class->$func($chat, $line);
if ($chat->isAdmin)
{
$chat->dccSend("ADMIN " . irc::myStrToUpper($cmdLower) . " Requested");
}
else
{
$chat->dccSend("CLIENT " . irc::myStrToUpper($cmdLower) . " Requested");
}
}
else
{
$chat->dccSend("Invalid Command: " . $line['cmd']);
}
}
public static function createLine
($rawLine) {
$lineCount =
count($rawLineArray);
if ($lineCount < 1)
{
return false;
}
else if ($lineCount == 1)
{
$line['cmd'] = irc::myStrToLower($rawLine);
$line['nargs'] = 0;
$line['query'] = "";
}
else
{
$line['nargs'] = 0;
$line['cmd'] = irc::
myStrToLower(array_shift($rawLineArray));
while (($arg =
array_shift($rawLineArray)) !==
NULL) // NULL fixed contributed by cortex, 05/01/05 {
{
continue;
}
$line['arg' . ++$line['nargs']] = $arg;
if ($line['nargs'] > MAX_ARGS-1)
{
break;
}
}
}
return $line;
}
public function parseLine($line)
{
if (DEBUG==1)
{
//print_r($line);
}
if ($this->ircClass->checkIgnore($line['from']))
{
return;
}
switch($line['cmd'])
{
case "PRIVMSG":
$args = $this->createLine($line['text']);
$cmdLower = irc::myStrToLower($args['cmd']);
if (isset($this->
cmdList['priv'][$cmdLower])) {
if ($this->cmdList['priv'][$cmdLower]['active'] == true)
{
$theCase = $this->ircClass->floodCheck($line);
switch ($theCase)
{
case STATUS_NOT_BANNED:
if ($this->cmdList['priv'][$cmdLower]['inform'] == true)
{
$this->dccClass->dccInform("Sending " . irc::myStrToUpper($line['text']) . " to " . $line['fromNick']);
}
$this->cmdList['priv'][$cmdLower]['usage']++;
$func = $this->cmdList['priv'][$cmdLower]['function'];
$module = $this->cmdList['priv'][$cmdLower]['module'];
$class = $this->cmdList['file'][$module]['class'];
if ($this->ircClass->getTextQueueLength() > 5)
{
$this->ircClass->notice($line['fromNick'], "Request Queued. Please wait " . $this->ircClass->getTextQueueLength() . " seconds for your data.", 0);
}
$class->$func($line, $args);
break;
case STATUS_JUST_BANNED:
$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.");
$this->dccClass->dccInform("BAN: (*!". irc::myStrToUpper($line['fromHost']) . "): " . $line['fromNick'] . " is on ignore for " . $this->ircClass->getClientConf('floodtime') . " seconds.");
break;
case STATUS_ALREADY_BANNED:
break;
}
}
else
{
$this->dccClass->dccInform("FUNCTION: " . $line['fromNick'] . " attempted to use deactivated command '" . $cmdLower . "'");
}
}
else
{
if ($line['to'] == $this->ircClass->getNick())
{
{
$this->ircClass->floodCheck($line);
$this->parseCtcp($line);
}
else
{
$this->dccClass->dccInform("PRIVMSG: <" . $line['fromNick'] . "> " . $line['text']);
}
}
else
{
{
$this->parseCtcp($line, "CHAN: " . $line['to']);
}
else
{
$chanData = $this->ircClass->getChannelData($line['to']);
if ($chanData == NULL)
{
$this->dccClass->dccInform("CHAN PRIVMSG [".$line['to']."]: <" . $line['fromNick'] . "> " . $line['text']);
}
}
}
}
break;
case "MODE":
break;
case "NOTICE":
$chan = $line['to'] != $this->ircClass->getNick() ? ":" . $line['to'] : "";
$this->dccClass->dccInform("NOTICE: <" . ($line['fromNick'] == "" ? $line['from'] : $line['fromNick']) . $chan . "> " . $line['text']);
break;
case "JOIN":
if ($line['fromNick'] == $this->ircClass->getNick())
{
$this->dccClass->dccInform("Joined: " . irc::myStrToUpper($line['text']));
}
break;
case "PART":
if ($line['fromNick'] == $this->ircClass->getNick())
{
$this->dccClass->dccInform("Parted: " . irc::myStrToUpper($line['to']));
}
break;
case "KICK":
if ($line['params'] == $this->ircClass->getNick())
{
$this->dccClass->dccInform("Kicked: " . $line['fromNick'] . " kicked you from " . $line['to']);
}
break;
case "ERROR":
$this->dccClass->dccInform("Server Error: " . $line['text']);
break;
case "366":
$channel = $params[0];
$this->dccClass->dccInform("Finished receiving NAMES list for " . $channel);
break;
case "005":
if ($this->ircClass->getServerConf("NETWORK") != "")
{
//Only show this once...
if (strpos($line['params'],
"NETWORK") !==
false) {
$this->dccClass->dccInform("Parsing IRC-Server specific configuration...");
$this->dccClass->dccInform("Network has been identified as " . $this->ircClass->getServerConf("NETWORK") .
"(" . $line['from'] . ")");
}
}
break;
case "315":
$this->dccClass->dccInform("Finished receiving WHO list for: " . $params[0]);
break;
case "368":
$this->dccClass->dccInform("Finished receiving ban list for: " . $params[0]);
break;
case "433":
$this->dccClass->dccInform("Nick collision! Unable to change your nick. Nickname already in use!");
break;
default:
break;
}
// Lets alias 004 to CONNECT, for the n00bs
if ($line['cmd'] == "004")
{
$line['cmd'] = "connect";
}
if ($line['cmd'] == "error")
{
$line['cmd'] = "disconnect";
}
// Action type handler
if (isset($this->
cmdList['action']) &&
strtolower($line['cmd']) ==
"privmsg") {
if (substr($line['text'],
0,
8) ==
chr(1) .
"ACTION ") {
$newLine = $line;
$newLine['text'] =
substr($line['text'],
8,
strlen($line['text']) -
9);
$sArgs = $this->createLine($newLine['text']);
foreach($this->cmdList['action'] AS $item)
{
$func = $item['function'];
$class = $this->cmdList['file'][$item['module']]['class'];
$class->$func($newLine, $sArgs);
}
}
}
// Raw type handler
if (isset($this->
cmdList['raw'])) {
{
$args = $this->createLine($line['text']);
}
foreach($this->cmdList['raw'] AS $item)
{
$func = $item['function'];
$class = $this->cmdList['file'][$item['module']]['class'];
$class->$func($line, $args);
}
}
// Here we will call any type
if (isset($this->
cmdList[irc::
myStrToLower($line['cmd'])])) {
{
$args = $this->createLine($line['text']);
}
foreach($this->cmdList[irc::myStrToLower($line['cmd'])] AS $item)
{
$func = $item['function'];
$class = $this->cmdList['file'][$item['module']]['class'];
$class->$func($line, $args);
}
}
{
}
}
/* Misc Functions */
private function parseCtcp($line, $msgs = "PRIVMSG")
{
$msg = "";
switch($cmd)
{
case "version":
$this->dccClass->dccInform("CTCP VERSION: " . $line['fromNick'] . " versioned us.");
break;
case "time":
$this->dccClass->dccInform("CTCP TIME: " . $line['fromNick'] . " requested the time.");
break;
case "uptime":
$this->dccClass->dccInform("CTCP UPTIME: " . $line['fromNick'] . " requested our uptime.");
break;
case "ping":
$this->dccClass->dccInform("CTCP PING: " . $line['fromNick'] . " pinged us.");
break;
case "dcc":
$this->dccParse($line, $vars, $query);
break;
}
if ($msg != "")
{
$this->
notice($this->
lVars['fromNick'],
chr(1) .
$msg .
chr(1));
}
if (isset($this->
cmdList['ctcp'][$cmd])) {
$func = $this->cmdList['ctcp'][$cmd]['function'];
$class = $this->cmdList['file'][$this->cmdList['ctcp'][$cmd]['module']]['class'];
$args = $this->createLine($cmd . " " . $query);
$class->$func($line, $args);
}
}
function dccParse($line, $vars, $txt)
{
if ($cVars < 1)
{
return;
}
$cmd = irc::myStrToUpper($vars[0]);
switch ($cmd)
{
case "CHAT":
if ($cVars == 4)
{
$iplong =
long2ip( (double
) $vars[2]);
$port = $vars[3];
$this->dccClass->addChat($line['fromNick'], $iplong, (int) $port, false, null);
}
break;
case "SEND":
if ($this->ircClass->getClientConf('upload') != 'yes')
{
$this->ircClass->notice($line['fromNick'], "DCC: I do not accept dcc transfers at this time.", 0);
break;
}
if ($cVars >= 5)
{
//Some bastard sent a file with spaces. Shit. Ass.
{
$second =
strpos($query,
chr(34),
$first +
1);
$filename =
substr($query,
$first +
1,
$second -
$first -
1);
$query =
str_replace("\"".
$filename.
"\"",
"file.ext",
$query);
}
else
{
$filename = $vars[1];
}
$iplong =
long2ip( (double
) $vars[2]);
$port = $vars[3];
$filesize = $vars[4];
$this->dccClass->addFile($line['fromNick'], $iplong, (int) $port, DOWNLOAD, $filename, $filesize);
}
break;
case "ACCEPT":
if ($cVars == 4)
{
$port = $vars[2];
$bytes = $vars[3];
$this->dccClass->dccAccept($port, $bytes);
}
break;
case "RESUME":
if ($cVars == 4)
{
$port = $vars[2];
$bytes = $vars[3];
$this->dccClass->dccResume($port, $bytes);
}
break;
}
}
}
/* Used to access dcc admin commands via private message */
class chat_wrapper {
public $nick;
private $ircClass;
public $isAdmin;
public function __construct($nick, $ircClass)
{
$this->nick = $nick;
$this->ircClass = $ircClass;
$this->isAdmin = 1;
}
public function dccSend($data, $to = null)
{
$this->ircClass->privMsg($this->nick, "--> " . $data);
}
public function disconnect($msg = "")
{
$this->ircClass->privMsg($this->nick, "Right........");
}
}
?>