private function getData($irc_msg) { $parsed = $this->parseIRCMessage($irc_msg); if (!$parsed) { return false; } $data['command'] = $parsed['command']; $data['raw'] = $irc_msg; switch ($data['command']) { case '001': // First message sent by an IRC server after successful auth $data['server'] = $parsed['servername']; $data['my_nick'] = $parsed['params'][0]; $data['welcome_message'] = $parsed['params'][1]; $this->Me = new IRC_User($data['my_nick'], $this); $this->users[$this->Me->id] = $this->Me; $this->sendWhois($this->Me->nick); /* $this->NickServ = new IRC_User('NickServ', $this); $this->users[$this->NickServ->id] = $this->NickServ; if(false !== $var = $this->getVar('nickserv_identify_command')) { $this->nickservIdentifyCommand = $var; } else { $this->NickServ->privmsg('ACC '.$this->Me->nick); $this->NickServ->privmsg('STATUS '.$this->Me->nick); } */ break; case '005': // ISUPPORT for ($i = 1; $i < sizeof($parsed['params']) - 1; $i++) { $tmp = explode('=', $parsed['params'][$i]); $name = strtoupper($tmp[0]); if (sizeof($tmp) == 2) { $this->supports[$name] = $tmp[1]; } else { $this->supports[$name] = true; } } break; case '311': // WHOIS reply $User = $this->getUser($parsed['params'][1]); $User->user = $parsed['params'][2]; $User->host = $parsed['params'][3]; $User->realname = $parsed['params'][5]; $User->banmask = $User->nick . '!' . $User->user . '@' . $User->host; $data['User'] = $User; break; case '315': // End of WHO list (Channel join complete) $data['Channel'] = $this->getChannel($parsed['params'][1]); break; case '324': // Server MODE reply $Channel = $this->getChannel($parsed['params'][1]); $modes = $parsed['params'][2]; $Channel->modes = array(); for ($i = 1; $i < strlen($modes); $i++) { $Channel->modes[$modes[$i]] = true; } break; case '332': // Server "get" TOPIC reply (Also on channel join) $Channel = $this->getChannel($parsed['params'][1]); $Channel->topic = $parsed['params'][2]; break; case '352': // Server WHO reply $Channel = $this->getChannel($parsed['params'][1]); $User = $this->getUser($parsed['params'][5]); $User->user = $parsed['params'][2]; $User->host = $parsed['params'][3]; $User->realname = substr($parsed['params'][7], 2); $User->banmask = $User->nick . '!' . $User->user . '@' . $User->host; if (!isset($Channel->users[$User->id])) { $Channel->addUser($User); } $modes = $parsed['params'][6]; $mode = ''; // Get the most significant mode, ignoring * (IRC OP) and the first 'H' char which isn't a mode for ($i = 1; $i < strlen($modes); $i++) { if ($modes[$i] != '*') { $mode = $modes[$i]; break; } } $User->modes[$Channel->id] = $mode; break; case '353': // Server NAMES reply $Channel = $this->getChannel($parsed['params'][2]); $users = explode(' ', $parsed['params'][3]); foreach ($users as $user) { preg_match('/^([+@%])?(.+)$/', $user, $arr); $mode = $arr[1]; $nick = $arr[2]; $User = $this->getUser($nick); $User->modes[$Channel->id] = $mode; } break; case '366': // Server End of NAMES list $data['Channel'] = $this->getChannel($parsed['params'][1]); break; case '433': // Sent on connect if nickname is already in use $data['nick'] = $parsed['params'][1]; break; case 'ERROR': // Sent when the server decides to close our connection $data['text'] = $parsed['params'][0]; if (libString::endsWith('(Excess Flood)', $data['text'])) { $this->onFlood(); $this->connectCooldown['cooldown'] = 20; $this->connectCooldown['last_connect'] = time(); } elseif (libString::endsWith('throttled', $data['text'])) { $this->connectCooldown['cooldown'] = 60; $this->connectCooldown['last_connect'] = time(); } fclose($this->socket); $this->socket = false; break; case 'JOIN': // Sent when the bot or a user joins a channel $User = $this->getUser($parsed['nick']); $User->banmask = $parsed['banmask']; $User->user = $parsed['user']; $User->host = $parsed['host']; $User->mode = ''; $Channel = $this->getChannel($parsed['params'][0]); $Channel->addUser($User); if ($User->id != $this->Me->id) { $data['User'] = $User; $data['Channel'] = $Channel; } break; case 'KICK': // Sent when a user gets kicked from a channel $User = $this->getUser($parsed['nick']); $Channel = $this->getChannel($parsed['params'][0]); $Victim = $this->getUser($parsed['params'][1]); $User->mode = $User->modes[$Channel->id]; $Victim->mode = $Victim->modes[$Channel->id]; $kick_message = $parsed['params'][2]; if ($Victim->id == $this->Me->id) { $Channel->remove(); } else { $data['Victim'] = $Victim; $Channel->removeUser($Victim); } $data['User'] = $User; $data['Channel'] = $Channel; $data['kick_message'] = $kick_message; break; case 'MODE': // TODO: Fix this up - It's not really correct if (sizeof($parsed['params']) >= 3) { // Sent if a mode for a user in a channel is changed // TODO: Many modes with 1 command $User = $this->getUser($parsed['nick']); $Victim = $this->getUser($parsed['params'][2]); $Channel = $this->getChannel($parsed['params'][0]); $Channel->sendNames(); $data['User'] = $User; $data['Channel'] = $Channel; $data['Victim'] = $Victim; $data['mode'] = $parsed['params'][1]; } else { if (isset($this->channels[$parsed['params'][0]])) { // Sent when the channel modes are changed $Channel = $this->getChannel($parsed['params'][0]); $modes = $parsed['params'][1]; $action = ''; for ($i = 0; $i < strlen($modes); $i++) { if ($modes[$i] == '+') { $action = 'add'; } elseif ($modes[$i] == '-') { $action = 'rm'; } else { switch ($action) { case 'add': $Channel->modes[$modes[$i]] = true; break; case 'rm': unset($Channel->modes[$modes[$i]]); break; } } } } else { // TODO: Sent on connect to show us our user modes on the server } } break; case 'NICK': // Sent when a user or the bot changes nick $User = $this->getUser($parsed['nick']); if ($User->id != $this->Me->id) { $data['User'] = $User; } $data['old_nick'] = $User->nick; $User->changeNick($parsed['params'][0]); break; case 'NOTICE': if (isset($parsed['nick'])) { // Sent when a user sends a notice $User = $this->getUser($parsed['nick']); $text = $parsed['params'][1]; /* if($User->id == 'nickserv') { // Sent when nickserv sends a notice $tmp = explode(' ', $parsed['params'][1]); if($tmp[0] == $this->Me->nick && $tmp[1] == 'ACC') { $this->nickservIdentifyCommand = 'ACC'; $this->saveVar('nickserv_identify_command', 'ACC'); } elseif($tmp[0] == 'STATUS' && $tmp[1] == $this->Me->nick) { $this->nickservIdentifyCommand = 'STATUS'; $this->saveVar('nickserv_identify_command', 'STATUS'); } $id = false; if($tmp[1] == 'ACC') $id = strtolower($tmp[0]); elseif($tmp[0] == 'STATUS') $id = strtolower($tmp[1]); if($id && isset($this->users[$id])) $this->users[$id]->nickservStatus = $tmp[2]; } */ $data['User'] = $User; $data['text'] = $text; } else { if (isset($parsed['servername'])) { $data['servername'] = $parsed['servername']; } else { $parsed['servername'] = false; } // $data['target'] = $parsed['params'][0]; $data['message'] = $parsed['params'][1]; if ($this->floodCooldown === false && preg_match('/Message to .+? throttled/', $data['message'])) { $this->onFlood(); } } break; case 'PART': // Sent when a user or the bot parts a channel $User = $this->getUser($parsed['nick']); $Channel = $this->getChannel($parsed['params'][0]); $User->mode = $User->modes[$Channel->id]; unset($User->modes[$Channel->id]); if ($User->id == $this->Me->id) { $Channel->remove(); } else { $Channel->removeUser($User); $data['User'] = $User; } $data['Channel'] = $Channel; if (isset($parsed['params'][1])) { $data['part_message'] = $parsed['params'][1]; } break; case 'PING': // Ping message sent from the server to see if we're still alive $data['challenge'] = $parsed['params'][0]; $this->sendPong($data['challenge']); break; case 'PONG': // Message sent by the server after we issued a PING $data['server'] = $parsed['params'][0]; $data['challenge'] = $parsed['params'][1]; $this->waitingForPong = false; break; case 'PRIVMSG': // Sent when a user sends a message to a channel where the bot is in, or to the bot itself if (!isset($this->users[strtolower($parsed['nick'])])) { $this->sendWhois($parsed['nick']); } $data['User'] = $this->getUser($parsed['nick']); // TODO: fail with todo at parseIRCMessage $data['text'] = isset($parsed['params'][1]) ? $parsed['params'][1] : ''; if (strtolower($parsed['params'][0]) == $this->Me->id) { $data['isQuery'] = true; $data['User']->mode = ''; } else { $data['isQuery'] = false; $data['Channel'] = $this->getChannel($parsed['params'][0]); $data['User']->mode = $data['User']->modes[$data['Channel']->id]; } if ($data['text'][0] == "") { $data['text'] = substr($data['text'], 1); if (substr($data['text'], -1) == "") { $data['text'] = substr($data['text'], 0, -1); } $data['command'] = 'vCTCP'; $tmp = explode(' ', $data['text'], 2); $data['ctcp_command'] = strtoupper($tmp[0]); if (isset($tmp[1])) { $data['text'] = $tmp[1]; } else { $data['text'] = ''; } if ($data['ctcp_command'] == 'ACTION') { unset($data['ctcp_command']); $data['command'] = 'vACTION'; } } break; case 'TOPIC': // Sent when a user changes the topic $User = $this->getUser($parsed['nick']); $Channel = $this->getChannel($parsed['params'][0]); $Channel->topic = $parsed['params'][1]; $data['User'] = $User; $data['Channel'] = $Channel; $data['topic'] = $parsed['params'][1]; break; case 'QUIT': // Sent when a user quits the server $User = $this->getUser($parsed['nick']); $User->remove(); $data['User'] = $User; // TODO: fail with todo at parseIRCMessage if (isset($parsed['params'][0])) { $data['quit_message'] = $parsed['params'][0]; } else { $data['quit_message'] = ''; } break; } return $data; }