x2Fusion

PHP-IRCd IRCd.php

Sep 12th, 2015
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 39.98 KB | None | 0 0
  1. <?php
  2.  
  3. $ircd = new IrcdServer();
  4.  
  5. class IrcdServer
  6. {
  7.     private $socket = null;
  8.     private $sockNum = 0;
  9.    
  10.     private $confArr = array();
  11.     private $sockArr = array();
  12.     private $quesArr = array();
  13.     private $connArr = array();
  14.     private $userArr = array();
  15.     private $chanArr = array();
  16.     private $operArr = array();
  17.    
  18.     private $nicktaken = false;
  19.    
  20.     public function __construct()
  21.     {
  22.         error_reporting(E_ALL);
  23.        
  24.         set_time_limit(0); // Run forever
  25.        
  26.         if(!file_exists('./configs.php'))
  27.         {
  28.             die("Error: Missing Configuration File './configs.php'");
  29.         }
  30.  
  31.         $this->confArr = include 'configs.php';
  32.  
  33.         $this->initConnect();
  34.     }
  35.    
  36.     private function initConnect()
  37.     {
  38.         // Create listen socket and bind
  39.         $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  40.         $socket_bind = socket_bind($this->socket, $this->confArr['bindaddr'], $this->confArr['bindport']);
  41.  
  42.         if(false === $socket_bind)
  43.         {
  44.             $error_code = socket_last_error();
  45.             $error_msg = socket_strerror($errorcode);
  46.             die("Could not create socket $error_code $error_msg");
  47.         }
  48.  
  49.         socket_listen($this->socket, $this->confArr['maxuser']);
  50.  
  51.         // Nonblocking socket
  52.         socket_set_nonblock($this->socket);
  53.  
  54.         echo "Running...\r\n\r\n";
  55.        
  56.         // Main loop
  57.         while(is_resource($this->socket))
  58.         {
  59.             $this->connHandler();
  60.         }
  61.     }
  62.    
  63.     private function connHandler()
  64.     {
  65.         if($x = @socket_accept($this->socket))
  66.         { // Is there a new socket?
  67.             // if (sizeof($this->connArr) == MAX_USERS) {
  68.             //  socket_write($x, 'Server full. Closing down.');
  69.             //}
  70.             //else
  71.             //{
  72.             $this->send(array('nick' => 'new user', 'sock' => $x), ':' . $this->confArr['hostname'] . ' NOTICE AUTH :*** Looking up your hostname...');
  73.            
  74.             socket_getpeername($x, $ip); // Get their IP
  75.             $host = $this->dns_timeout($ip); // Reverse DNS
  76.             socket_set_nonblock($x); // Nonblocking FTW
  77.            
  78.             $this->send(array('nick' => 'new user', 'sock' => $x), ':' . $this->confArr['hostname'] . ' NOTICE AUTH :*** Found your hostname');
  79.            
  80.             $this->connArr[] = array( // Add the user
  81.                 'nick'      => null,
  82.                 'sock'      => $x,
  83.                 'buf'       => '',
  84.                 'ip'        => $ip,
  85.                 'ident'     => null,
  86.                 'realname'  => null,
  87.                 'host'      => $host);
  88.                
  89.             $this->userArr[(int)$x] = array( // Add the info array
  90.                 'oper'  => false,
  91.                 'cloak' => $host);
  92.         }
  93.        
  94.         foreach($this->connArr as &$me)
  95.         { // Loop through connections
  96.             while(false != $c = trim($this->socket_normal_read($me['sock'])))
  97.             { // Read packets
  98.                 echo $me['nick'] . ' <<< ' . $c . "\n"; // Log to console
  99.                 $args = explode(' ', $c); // Get params
  100.                
  101.                 switch(strtoupper($args[0]))
  102.                 { // yay tabbing jump. srsly reduces file size.
  103.                     case 'NICK':
  104.                         $newnick = $args[1];
  105.                         $nicktaken = false; // Is nick in use?
  106.  
  107.                         // Sometimes clients send :nick instead of nick
  108.                         if(strpos($c, ' :') !== false)
  109.                         {
  110.                             $newnick = substr($c, strpos($c, ' :') + 2);
  111.                         }
  112.                        
  113.                         if(!$this->validate_nick($newnick))
  114.                         { // Invalid nick
  115.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 431 ' . $newnick . ' :Erroneous Nickname: You fail.');
  116.                             break;
  117.                         }
  118.  
  119.                         foreach($this->connArr as $him)
  120.                         { // Check if nick is in use
  121.                             if(strtolower($him['nick']) == strtolower($newnick))
  122.                             {
  123.                                 $nicktaken = true;
  124.                             }
  125.                         }
  126.  
  127.                         if($nicktaken)
  128.                         { // it IS in use, after all.
  129.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 433 ' . (($me['nick'] == null) ? '*' : $me['nick']) . ' ' . $newnick . ' :Nickname is already in use.');
  130.                             $this->nicktaken = true;
  131.                             break;
  132.                         }
  133.  
  134.                         if($me['nick'] == null)
  135.                         { // Is this the initial NICK?
  136.                             $me['nick'] = $newnick;
  137.                             $this->send($me, 'PING :tu.madre'); // Send ping and wait for USER. The ping is highly random btw.
  138.                             if($this->nicktaken)
  139.                             {
  140.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 001 ' . $me['nick'] . ' : ');
  141.                             }
  142.                         }
  143.                         else
  144.                         {
  145.                             $newme = $me; // Make a new user instance that will be inserted into channel nick lists
  146.                             $newme['nick'] = $newnick;
  147.                             $sentto = array(); // Who already got the NICK?
  148.                             foreach($this->chanArr as &$channel)
  149.                             { // Looking through the channels....
  150.                                 if(in_array($me, $channel['nicks']))
  151.                                 { // Is said user in this channel?
  152.                                     foreach($channel['nicks'] as $user)
  153.                                     { // Loop through the nicks in said channel
  154.                                         if(!in_array($user, $sentto))
  155.                                         { // User did not get the NICK yet
  156.                                             $this->send($user, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' NICK ' . $newnick);
  157.                                             $sentto[] = $user;
  158.                                         }
  159.                                     }
  160.                                     // Replace the channel listings with new nick. We need to search all the modes arrays too.
  161.                                     $arrs = array('nicks', 'owners', 'protected', 'oped', 'halfoped', 'voiced');
  162.                                     foreach($arrs as $arr)
  163.                                     {
  164.                                         if(in_array($me, $channel[$arr]))
  165.                                         {
  166.                                             $this->nick_removal($me['nick'], $channel[$arr]);
  167.                                             $channel[$arr][] = $newme;
  168.                                         }
  169.                                     }
  170.                                 }
  171.                             }
  172.                             $me['nick'] = $newnick;
  173.                         }
  174.                     break;
  175.                    
  176.                     case 'USER':
  177.                         if(sizeof($args) < 5)
  178.                         { // Not enough params
  179.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 461 :USER Not enough parameters');
  180.                             break;
  181.                         }
  182.  
  183.                         $newident = $args[1];
  184.                         $newrealname = $args[4];
  185.  
  186.                         // Check for :
  187.                         if(strpos($c, ' :') !== false)
  188.                         {
  189.                             $newrealname = substr($c, strpos($c, ' :') + 2);
  190.                         }
  191.                        
  192.                         if($me['ident'] == null)
  193.                         { // You can only register once.
  194.                             if(!$this->nicktaken)
  195.                             {
  196.                                 $me['ident'] = $newident;
  197.                                 $me['realname'] = $newrealname;
  198.                                 $config['version'] = '1.0-beta';
  199.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 001 ' . $me['nick'] . ' :Welcome to the ' . $this->confArr['servname'] . ' IRC Network ' . $me['nick'] . '!' . $me['ident'] . '@' . $me['host']);
  200.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 002 ' . $me['nick'] . ' :Your host is ' . $this->confArr['hostname'] . ', running version Fusion '.$config['version']);
  201.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 003 ' . $me['nick'] . ' :This server was created Fri Jul 13 19:22:25 2007');
  202.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 004 ' . $me['nick'] . ' ' . $this->confArr['hostname'] . ' Fusion '.$config['version'].' iowghraAsORTVSxNCWqBzvdHtGp lvhopsmntikrRcaqOALQbSeIKVfMCuzNTGj');
  203.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 005 ' . $me['nick'] . ' CMDS=KNOCK,MAP,DCCALLOW,USERIP NAMESX SAFELIST HCN MAXCHANNELS=10 CHANLIMIT=#:10 MAXLIST=b:60,e:60,I:60 NICKLEN=30 CHANNELLEN=32 TOPICLEN=307 KICKLEN=307 AWAYLEN=307 MAXTARGETS=20 :are supported by this server');
  204.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 005 ' . $me['nick'] . ' WALLCHOPS WATCH=128 SILENCE=15 MODES=12 CHANTYPES=# PREFIX=(qaohv)~&@%+ CHANMODES=beI,kfL,lj,psmntirRcOAQKVCuzNSMTG NETWORK=' . $this->confArr['servname'] . ' CASEMAPPING=ascii EXTBAN=~,cqnr ELIST=MNUCT STATUSMSG=~&@%+ EXCEPTS :are supported by this server');
  205.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 005 ' . $me['nick'] . ' INVEX :are supported by this server');
  206.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 251 ' . $me['nick'] . ' :There are ' . sizeof($this->connArr) . ' user(s) and 0 invisible user(s) on 1 server(s)');
  207.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 252 ' . $me['nick'] . ' ' . sizeof($this->operArr) . ' :operator(s) online');
  208.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 254 ' . $me['nick'] . ' ' . sizeof($this->chanArr) . ' :channel(s) formed');
  209.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 255 ' . $me['nick'] . ' :I have ' . (sizeof($this->connArr)) . ' client(s) and 1 server(s)');
  210.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 265 ' . $me['nick'] . ' :Current Local Users: ' . (sizeof($this->connArr)) . '  Max: ' . (sizeof($this->connArr) + 1));
  211.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 266 ' . $me['nick'] . ' :Current Global Users: ' . (sizeof($this->connArr)) . '  Max: ' . (sizeof($this->connArr) + 1));
  212.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 375 ' . $me['nick'] . ' :###########################################');
  213.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 375 ' . $me['nick'] . ' :- Message of the Day -');
  214.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 372 ' . $me['nick'] . ' :- ' . implode("\r\n:" . $this->confArr['hostname'] . ' 372 ' . $me['nick'] . ' :- ', explode("\n", $this->confArr['motd'])));
  215.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 376 ' . $me['nick'] . ' :End of /MOTD command.');
  216.                             }
  217.                         }
  218.                         else
  219.                         { // Initial USER was already sent.
  220.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 462 :You may not reregister');
  221.                         }
  222.                     break;
  223.                    
  224.                     case 'MOTD':
  225.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 375 ' . $me['nick'] . ' :- Message of the Day -');
  226.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 372 ' . $me['nick'] . ' :- ' . implode("\r\n:" . $this->connArr['hostname'] . ' 372 ' . $me['nick'] . ' :- ', explode("\n", $this->confArr['motd'])));
  227.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 376 ' . $me['nick'] . ' :End of /MOTD command.');
  228.                     break;
  229.  
  230.                     case 'LUSERS':
  231.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 251 ' . $me['nick'] . ' :There are ' . sizeof($this->connArr) . ' users and 1 invisible on 1 server(s)');
  232.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 252 ' . $me['nick'] . ' 1 :operator(s) online');
  233.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 254 ' . $me['nick'] . ' ' . sizeof($this->chanArr) . ' :channels formed');
  234.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 255 ' . $me['nick'] . ' :I have ' . (sizeof($this->connArr) + 1) . ' clients and 1 server(s)');
  235.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 265 ' . $me['nick'] . ' :Current Local Users: ' . (sizeof($this->connArr) + 1) . '  Max: ' . (sizeof($this->connArr) + 1));
  236.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 266 ' . $me['nick'] . ' :Current Global Users: ' . (sizeof($this->connArr) + 1) . '  Max: ' . (sizeof($this->connArr) + 1));
  237.                     break;
  238.  
  239.                     case 'VERSION':
  240.                         $config['version'] = '1.0-beta';
  241.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 005 ' . $me['nick'] . ' Fusion '.$config['version'].' ' . $this->connArr['hostname'] . ' FinWXOoZE3');
  242.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 005 ' . $me['nick'] . ' CMDS=KNOCK,MAP,DCCALLOW,USERIP NAMESX SAFELIST HCN MAXCHANNELS=10 CHANLIMIT=#:10 MAXLIST=b:60,e:60,I:60 NICKLEN=30 CHANNELLEN=32 TOPICLEN=307 KICKLEN=307 AWAYLEN=307 MAXTARGETS=20 :are supported by this server');
  243.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 005 ' . $me['nick'] . ' WALLCHOPS WATCH=128 SILENCE=15 MODES=12 CHANTYPES=# PREFIX=(qaohv)~&@%+ CHANMODES=beI,kfL,lj,psmntirRcOAQKVCuzNSMTG NETWORK=' . $this->confArr['servname'] . ' CASEMAPPING=ascii EXTBAN=~,cqnr ELIST=MNUCT STATUSMSG=~&@%+ EXCEPTS :are supported by this server');
  244.                         $this->send($me, ':' . $this->connArr['hostname'] . ' 005 ' . $me['nick'] . ' INVEX :are supported by this server');
  245.                     break;
  246.  
  247.                     case 'INVITE':
  248.                         $who = $args[1];
  249.                         $target = $args[2];
  250.  
  251.                         if (isset($this->chanArr[strtolower($target)]))
  252.                         { // Does the channel even exist?
  253.                             $channel = $this->chanArr[strtolower($target)];
  254.                             if (!in_array($me, $channel['nicks']))
  255.                             { // Is user even in the channel?
  256.                                 $this->send($me, ':' . $this->connArr['hostname'] . ' 442 ' . $me['nick'] . ' ' . $target . ' :You\'re not on that channel');
  257.                                 break;
  258.                             }
  259.                             $found = false; // Make sure we find the target
  260.                             foreach($this->connArr as $him)
  261.                             { // Find target
  262.                                 if (strtolower($him['nick']) == strtolower($who))
  263.                                 {
  264.                                     $found = $him;
  265.                                 }
  266.                             }
  267.                             if($found === false)
  268.                             { // User offline
  269.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 401 ' . $me['nick'] . ' ' . $who . ' :No such nick');
  270.                                 break;
  271.                             }
  272.                             if(in_array($found, $channel['nicks']))
  273.                             { // Is target already in the channel?
  274.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 443 ' . $me['nick'] . ' ' . $who . ' ' . $target . ' :is already on channel');
  275.                                 break;
  276.                             }
  277.                             // Invite to channel
  278.                             $this->send($found, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' INVITE ' . $who . ' ' . $target);
  279.                         }
  280.                         else
  281.                         { // Channel does not exist!
  282.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 403 ' . $me['nick'] . ' ' . $target . ' :No such nick/channel');
  283.                             break;
  284.                         }
  285.                     break;
  286.  
  287.                     case 'PRIVMSG':
  288.                         $target = $args[1];
  289.                         $message = substr($c, strpos($c, ' :') + 2);
  290.                         if(isset($this->chanArr[strtolower($target)]))
  291.                         {
  292.                             foreach($this->chanArr[strtolower($target)]['nicks'] as $user)
  293.                             {
  294.                                 // User is not self?
  295.                                 if ($user !== $me)
  296.                                     $this->send($user, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' PRIVMSG ' . $target . ' :' . $message);
  297.                             }
  298.                         }
  299.                         else
  300.                         {
  301.                             foreach($this->connArr as $him)
  302.                             { // Find target
  303.                                 if (strtolower($him['nick']) == strtolower($target))
  304.                                 {
  305.                                     $this->send($him, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' PRIVMSG ' . $target . ' :' . $message);
  306.                                 }
  307.                             }
  308.                         }
  309.                     break;
  310.                    
  311.                     case 'WHOIS':
  312.                         $target = $args[1];
  313.                         foreach($conn as $him)
  314.                         {
  315.                             if(strtolower($him['nick']) == strtolower($target))
  316.                             { // Find target
  317.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 311 ' . $me['nick'] . ' ' . $him['nick'] . ' ' . $him['ident'] . ' ' . $this->userArr[(int)$him['sock']]['cloak'] . ' * :' . $him['realname']);
  318.  
  319.                                 //$this->send($me, ':' . $this->confArr['hostname'] . ' 307 ' . $me['nick'] . ' ' . $him['nick'] . ' :is a registered nick');
  320.  
  321.                                 $chans = array();
  322.                                 foreach($this->chanArr as $channel => &$channel_arr)
  323.                                 { // Looking through the channels....
  324.                                     if(in_array($him, $channel_arr['nicks']))
  325.                                     { // Is said user in this channel?
  326.                                         $chans[] = $channel;
  327.                                     }
  328.                                 }
  329.                                 if(count($chans) > 0)
  330.                                 {
  331.                                     $this->send($me, ':' . $this->confArr['hostname'] . ' 319 ' . $me['nick'] . ' ' . $him['nick'] . ' :' . implode(' ', $chans));
  332.                                 }
  333.  
  334.                                 send($me, ':' . $this->confArr['hostname'] . ' 312 ' . $me['nick'] . ' ' . $him['nick'] . ' ' . $this->confArr['hostname'] . ' :' . $this->confArr['hostname']);
  335.  
  336.                                 if($this->userArr[(int)$him['sock']]['oper'])
  337.                                 {
  338.                                     $this->send($me, ':' . $this->confArr['hostname'] . ' 313 ' . $me['nick'] . ' ' . $him['nick'] . ' :is a Network Administrator');
  339.                                 }
  340.  
  341.                                 //$this->send($me, ':' . $this->confArr['hostname'] . ' 310 ' . $me['nick'] . ' ' . $him['nick'] . ' :is available for help.
  342.  
  343.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 318 ' . $me['nick'] . ' ' . $him['nick'] . ' :End of /WHOIS list.');
  344.                             }
  345.                         }
  346.                     break;
  347.  
  348.                     case 'OPER':
  349.                         if (count($args) == 3) {
  350.                             $user = $args[1];
  351.                             $pass = $args[2];
  352.                             if((isset($this->confArr['opers'][$user])) && ($this->confArr['opers'][$user] == $pass))
  353.                             {
  354.                                 $this->userArr[(int)$me['sock']]['oper'] = true;
  355.                                 $this->operArr[$me['nick']] = true;
  356.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 381 ' . $me['nick'] . ' :You have entered... the Twilight Zone!');
  357.                                 break;
  358.                             }
  359.                         }
  360.                         $this->send($me, ':' . $this->confArr['hostname'] . ' 491 ' . $me['nick'] . ' :Only few of mere mortals may try to enter the twilight zone');
  361.                     break;
  362.                    
  363.                     case 'KILL':
  364.                         if($this->userArr[(int)$me['sock']]['oper'])
  365.                         { // You have to be opered!
  366.                             if(count($args) >= 3)
  367.                             { // We need a reason
  368.                                 $target = $args[1];
  369.                                 $reason = $args[2];
  370.                                 if(strpos($c, ' :') !== false)
  371.                                 {
  372.                                     $reason = substr($c, strpos($c, ' :') + 2);
  373.                                 }
  374.                                
  375.                                 foreach($this->connArr as $him)
  376.                                 { // Find target
  377.                                     if(strtolower($him['nick']) == strtolower($target))
  378.                                     {
  379.                                         $this->kill($him, 'Killed (' . $me['nick'] . ' (' . $reason . '))');
  380.                                     }
  381.                                 }
  382.                             }
  383.                             else
  384.                             {
  385.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 461 ' . $me['nick'] . ' KILL :Not enough parameters');
  386.                             }
  387.                         }
  388.                         else
  389.                         {
  390.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 481 ' . $me['nick'] . ' :Permission Denied- You do not have the correct IRC operator privileges');
  391.                         }
  392.                     break;
  393.  
  394.                     case 'CHGHOST':
  395.                         if($this->userArr[(int)$me['sock']]['oper'])
  396.                         { // You have to be opered!
  397.                             if(count($args) >= 3)
  398.                             { // We need a target and mask
  399.                                 $target = $args[1];
  400.                                 $newmask = $args[2];
  401.  
  402.                                 foreach($conn as $him)
  403.                                 { // Find target
  404.                                     if(strtolower($him['nick']) == strtolower($target))
  405.                                     {
  406.                                         $this->userArr[(int)$him['sock']]['cloak'] = $newmask;
  407.                                     }
  408.                                 }
  409.                             }
  410.                             else
  411.                             {
  412.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 461 ' . $me['nick'] . ' CHGHOST :Not enough parameters');
  413.                             }
  414.                         }
  415.                         else
  416.                         {
  417.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 481 ' . $me['nick'] . ' :Permission Denied- You do not have the correct IRC operator privileges');
  418.                         }
  419.                     break;
  420.  
  421.                     case 'REHASH':
  422.                         if($this->userArr[(int)$me['sock']]['oper'])
  423.                         { // You have to be opered!
  424.                             $this->confArr = include 'configs.php';
  425.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 382 ' . $me['nick'] . ' configs.php :Rehashing');
  426.                         }
  427.                         else
  428.                         {
  429.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 481 ' . $me['nick'] . ' :Permission Denied- You do not have the correct IRC operator privileges');
  430.                         }
  431.                     break;
  432.  
  433.                     case 'NOTICE':
  434.                         $target = $args[1];
  435.                         $message = substr($c, strpos($c, ' :') + 2);
  436.                         if(isset($this->chanArr[strtolower($target)]))
  437.                         {
  438.                             foreach($$this->chanArr[strtolower($target)]['nicks'] as $user)
  439.                             { // Find target
  440.                                 if (!($user == $me))
  441.                                 {
  442.                                     $this->send($user, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' NOTICE ' . $target . ' :' . $message);
  443.                                 }
  444.                             }
  445.                         }
  446.                         else
  447.                         {
  448.                             foreach ($this->connArr as $him)
  449.                             { // Find target
  450.                                 if(strtolower($him['nick']) == strtolower($target))
  451.                                 {
  452.                                     $this->send($him, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' NOTICE ' . $target . ' :' . $message);
  453.                                 }
  454.                             }
  455.                         }
  456.                     break;
  457.                    
  458.                     case 'JOIN':
  459.                         $targets = explode(',', $args[1]); // This line allows channel lists (like JOIN #a,#b,#c)
  460.  
  461.                         foreach($targets as $target)
  462.                         { // Loop through each supplied channel
  463.                             if(!$this->validate_chan($target))
  464.                             { // Valid name?
  465.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 403 ' . $target . ' :No such channel');
  466.                                 break;
  467.                             }
  468.  
  469.                             if(isset($this->chanArr[strtolower($target)]))
  470.                             { // Does the channel exist yet?
  471.                                 $channel = $this->chanArr[strtolower($target)];
  472.                                 if(in_array($me, $channel['nicks']))
  473.                                 {
  474.                                     break; // Is user already in the channel?
  475.                                 }    
  476.  
  477.                                 $names = $me['nick'];
  478.                                 foreach ($channel['nicks'] as $user)
  479.                                 { // Inform everyone and also build up /names
  480.                                     $this->send($user, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' JOIN ' . $target);
  481.                                     $chars = ''; // Handle modes
  482.                                     $search = array('~' => 'owners', '&' => 'owners', '@' => 'oped', '%' => 'halfoped', '+' => 'voiced');
  483.                                     foreach($search as $search_char => $search_name)
  484.                                     {
  485.                                         if(in_array($user, $channel[$search_name]))
  486.                                         {
  487.                                             $chars .= $search_char;
  488.                                         }
  489.                                     }
  490.                                     $names .= ' ' . $chars . $user['nick'];
  491.                                 }
  492.                             }
  493.                             else
  494.                             { // Make a new channel
  495.                                 $channel = array('name' => strtolower($target), 'nicks' => array(), 'bans' => array(), 'excepts' => array(), 'invites' => array(), 'owners' => array(), 'protected' => array(), 'oped' => array($me), 'halfoped' => array(), 'voiced' => array(), 'modes' => 'nt');
  496.                                 $this->chanArr[strtolower($target)] = $channel;
  497.                                 $names = '@' . $me['nick']; // User is oped
  498.                             }
  499.                            
  500.                             $channel['nicks'][] = $me; // Add user to nicklist
  501.                             $this->send($me, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' JOIN ' . $target);
  502.                            
  503.                             if(isset($channel['topic']))
  504.                             { // Send topic, if any
  505.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 332 ' . $me['nick'] . ' ' . $target . ' :' . $channel['topic']);
  506.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 333 ' . $me['nick'] . ' ' . $target . ' ' . $channel['topic_who'] . ' ' . $channel['topic_time']);
  507.                             }
  508.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 353 ' . $me['nick'] . ' = ' . $target . ' :' . $names);
  509.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 366 ' . $me['nick'] . ' ' . $target . ' :End of /NAMES list.');
  510.                             $this->chanArr[strtolower($target)] = $channel;
  511.                         }
  512.                     break;
  513.                    
  514.                     case 'TOPIC':
  515.                         $target = $args[1];
  516.                         if(isset($this->chanArr[strtolower($target)]))
  517.                         { // Does the channel exist?
  518.                             $channel = $this->chanArr[strtolower($target)];
  519.                             if(strpos($c, ' :') === false)
  520.                             { // Not setting topic.
  521.                                 if(isset($channel['topic']))
  522.                                 { // Send topic, damnit!
  523.                                     $this->send($me, ':' . $this->confArr['hostname'] . ' 332 ' . $me['nick'] . ' ' . $target . ' :' . $channel['topic']);
  524.                                     $this->send($me, ':' . $this->confArr['hostname'] . ' 333 ' . $me['nick'] . ' ' . $target . ' ' . $channel['topic_who'] . ' ' . $channel['topic_time']);
  525.                                 }
  526.                                 else
  527.                                 { // There isn't a topic yet.
  528.                                     $this->send($me, ':' . $this->confArr['hostname'] . ' 331 ' . $me['nick'] . ' ' . $target . ' :No topic is set.');
  529.                                 }
  530.                             }
  531.                             else
  532.                             { // Setting the topic! fun!
  533.                                 $message = substr($c, strpos($c, ' :') + 2);
  534.                                 $channel['topic'] = $message;
  535.                                 $channel['topic_time'] = time();
  536.                                 $channel['topic_who'] = $me['nick'];
  537.                                 foreach($channel['nicks'] as $user)
  538.                                 { // Inform of new topic
  539.                                     $this->send($user, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' TOPIC ' . $target . ' :' . $message);
  540.                                 }
  541.                                 $this->chanArr[strtolower($target)] = $channel;
  542.                             }
  543.                         }
  544.                         else
  545.                         { // No such channel.
  546.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 403 ' . $me['nick'] . ' ' . $target . ' :No such channel');
  547.                         }
  548.                     break;
  549.                    
  550.                     case 'MODE': // TODO: Code mode setting!
  551.                         $target = $args[1];
  552.                         if(isset($this->chanArr[strtolower($target)]))
  553.                         {// Channel exist?
  554.                             $channel = $this->chanArr[strtolower($target)];
  555.                             if(sizeof($args) == 2)
  556.                             { // Getting modes, yay
  557.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 324 ' . $me['nick'] . ' ' . $target . ' +' . $channel['modes']);
  558.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 329 ' . $me['nick'] . ' ' . $target . ' ' . time());
  559.                             }
  560.                             else
  561.                             { // Still working on this, settings modes. ATM dones't do much.
  562.                                 //var_dump($args);
  563.                                 $mode_args = array_slice($args, 3);
  564.                                 $modes = $args[2];
  565.                                 //var_dump($mode_args);
  566.                                 $mode_changes = '';
  567.                                 $mode_change_args = array();
  568.                                 $mode_change_sign = -1;
  569.                                 $sign = true;
  570.  
  571.                                 $oped = in_array($me, $channel['oped']);
  572.  
  573.                                 for($i = 0; $i < strlen($modes); $i++)
  574.                                 { // Loop through each charactor in the mode request
  575.                                     $char = $modes{$i};
  576.                                     switch($char)
  577.                                     { // Go by which char it is!
  578.                                         case '+': // Set sign to ON
  579.                                             $sign = true;
  580.                                         break;
  581.                                         case '-': // Set sign to OFF
  582.                                             $sign = false;
  583.                                         break;
  584.                                         case 'o': // Op or deop
  585.                                             if($oped)
  586.                                             {
  587.                                                 $found = false;
  588.                                                 $mode_target = strtolower(array_shift($mode_args));
  589.                                                 foreach($channel['nicks'] as $user)
  590.                                                 { // Look for target
  591.                                                     if(strtolower($user['nick']) == $mode_target)
  592.                                                     {
  593.                                                         $found = $user;
  594.                                                     }
  595.                                                 }
  596.                                                 if($found !== false)
  597.                                                 {
  598.                                                     if($mode_change_sign == $sign)
  599.                                                     {
  600.                                                         $mode_changes = 'o';
  601.                                                     }
  602.                                                     if($mode_change_sign == !$sign)
  603.                                                     {
  604.                                                         $mode_change_sign == $sign;
  605.                                                         $mode_changes = ($sign ? '+' : '-') . 'o';
  606.                                                     }
  607.                                                     if($mode_change_sign == -1)
  608.                                                     {
  609.                                                         $mode_change_sign == $sign;
  610.                                                         $mode_changes = ($sign ? '+' : '-') . 'o';
  611.                                                     }
  612.                                                     $mode_change_args[] = $found['nick'];
  613.                                                     if($sign && !in_array($found, $channel['oped']))
  614.                                                     {
  615.                                                         $channel['oped'][] = $found;
  616.                                                     }
  617.                                                     if(!$sign && in_array($found, $channel['oped']))
  618.                                                     {
  619.                                                         $this->nick_removal($found['nick'], $channel['oped']);
  620.                                                     }
  621.                                                 }
  622.                                             }
  623.                                         break;
  624.                                         case 'v': // Voice/devoice
  625.                                             if($oped)
  626.                                             {
  627.                                                 $found = false;
  628.                                                 $mode_target = strtolower(array_shift($mode_args));
  629.                                                 foreach($channel['nicks'] as $user)
  630.                                                 { // Look for target
  631.                                                     if(strtolower($user['nick']) == $mode_target)
  632.                                                     {
  633.                                                         $found = $user;
  634.                                                     }
  635.                                                 }
  636.                                                 if($found !== false)
  637.                                                 {
  638.                                                     if ($mode_change_sign == $sign)
  639.                                                     {
  640.                                                         $mode_changes = 'v';
  641.                                                     }
  642.                                                     if ($mode_change_sign == !$sign)
  643.                                                     {
  644.                                                         $mode_change_sign == $sign;
  645.                                                         $mode_changes = ($sign ? '+' : '-') . 'v';
  646.                                                     }
  647.                                                     if ($mode_change_sign == -1)
  648.                                                     {
  649.                                                         $mode_change_sign == $sign;
  650.                                                         $mode_changes = ($sign ? '+' : '-') . 'v';
  651.                                                     }
  652.                                                     $mode_change_args[] = $found['nick'];
  653.                                                     if ($sign && !in_array($found, $channel['voiced']))
  654.                                                     {
  655.                                                         $channel['voiced'][] = $found;
  656.                                                     }
  657.                                                     if (!$sign && in_array($found, $channel['voiced']))
  658.                                                     {
  659.                                                         $this->nick_removal($found['nick'], $channel['voiced']);
  660.                                                     }
  661.                                                 }
  662.                                             }
  663.                                         break;
  664.                                     }
  665.                                 }
  666.  
  667.                                 /* $message = substr($c, strpos($c, ' :') + 2);
  668.                                   $channel['topic'] = $message;
  669.                                   $channel['topic_time'] = time();
  670.                                   $channel['topic_who'] = $me['nick']; */
  671.                                 if($mode_changes != '')
  672.                                 {
  673.                                     foreach($channel['nicks'] as $user)
  674.                                     {
  675.                                         $this->send($user, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' MODE ' . $target . ' ' . $mode_changes . ' ' . implode(' ', $mode_change_args));
  676.                                     }
  677.                                     $this->chanArr[strtolower($target)] = $channel;
  678.                                 }
  679.                             }
  680.                         }
  681.                         else
  682.                         { // No such channel (nick mdoes are not coded for yet)
  683.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 403 ' . $me['nick'] . ' ' . $target . ' :No such channel');
  684.                         }
  685.                     break;
  686.                    
  687.                     case 'SAMODE': // TODO: Code mode setting!
  688.                         if($this->userArr[(int)$me['sock']]['oper'])
  689.                         { // You have to be opered!
  690.                             if(count($args) >= 3)
  691.                             { // We need a target and modes
  692.                                 $target = $args[1];
  693.  
  694.                                 if(isset($this->chanArr[strtolower($target)]))
  695.                                 {// Channel exist?
  696.                                     $channel = $this->chanArr[strtolower($target)];
  697.                                     if(sizeof($args) == 2)
  698.                                     { // Getting modes, yay
  699.                                         $this->send($me, ':' . $this->confArr['hostname'] . ' 324 ' . $me['nick'] . ' ' . $target . ' +' . $channel['modes']);
  700.                                         $this->send($me, ':' . $this->confArr['hostname'] . ' 329 ' . $me['nick'] . ' ' . $target . ' ' . time());
  701.                                     }
  702.                                     else
  703.                                     { // Still working on this, settings modes. ATM dones't do much.
  704.                                         //var_dump($args);
  705.                                         $mode_args = array_slice($args, 3);
  706.                                         $modes = $args[2];
  707.                                         //var_dump($mode_args);
  708.                                         $mode_changes = '';
  709.                                         $mode_change_args = array();
  710.                                         $mode_change_sign = -1;
  711.                                         $sign = true;
  712.                                         for($i = 0; $i < strlen($modes); $i++)
  713.                                         { // Loop through each charactor in the mode request
  714.                                             $char = $modes{$i};
  715.                                             switch($char)
  716.                                             { // Go by which char it is!
  717.                                                 case '+': // Set sign to ON
  718.                                                     $sign = true;
  719.                                                 break;
  720.                                                 case '-': // Set sign to OFF
  721.                                                     $sign = false;
  722.                                                 break;
  723.                                                 case 'o': // Op or deop
  724.                                                     $found = false;
  725.                                                     $mode_target = strtolower(array_shift($mode_args));
  726.                                                     foreach($channel['nicks'] as $user)
  727.                                                     { // Look for target
  728.                                                         if (strtolower($user['nick']) == $mode_target)
  729.                                                         {
  730.                                                             $found = $user;
  731.                                                         }
  732.                                                     }
  733.                                                     if ($found !== false)
  734.                                                     {
  735.                                                         if ($mode_change_sign == $sign)
  736.                                                         {
  737.                                                             $mode_changes = 'o';
  738.                                                         }
  739.                                                         if ($mode_change_sign == !$sign)
  740.                                                         {
  741.                                                             $mode_change_sign == $sign;
  742.                                                             $mode_changes = ($sign ? '+' : '-') . 'o';
  743.                                                         }
  744.                                                         if ($mode_change_sign == -1)
  745.                                                         {
  746.                                                             $mode_change_sign == $sign;
  747.                                                             $mode_changes = ($sign ? '+' : '-') . 'o';
  748.                                                         }
  749.                                                         $mode_change_args[] = $found['nick'];
  750.                                                         if ($sign && !in_array($found, $channel['oped']))
  751.                                                         {
  752.                                                             $channel['oped'][] = $found;
  753.                                                         }
  754.                                                         if (!$sign && in_array($found, $channel['oped']))
  755.                                                         {
  756.                                                             $this->nick_removal($found['nick'], $channel['oped']);
  757.                                                         }
  758.                                                     }
  759.                                                 break;
  760.                                                 case 'v': // Voice/devoice
  761.                                                     $found = false;
  762.                                                     $mode_target = strtolower(array_shift($mode_args));
  763.                                                     foreach($channel['nicks'] as $user)
  764.                                                     { // Look for target
  765.                                                         if(strtolower($user['nick']) == $mode_target)
  766.                                                         {
  767.                                                             $found = $user;
  768.                                                         }
  769.                                                     }
  770.                                                     if($found !== false)
  771.                                                     {
  772.                                                         if($mode_change_sign == $sign)
  773.                                                         {
  774.                                                             $mode_changes = 'v';
  775.                                                         }
  776.                                                         if($mode_change_sign == !$sign)
  777.                                                         {
  778.                                                             $mode_change_sign == $sign;
  779.                                                             $mode_changes = ($sign ? '+' : '-') . 'v';
  780.                                                         }
  781.                                                         if($mode_change_sign == -1)
  782.                                                         {
  783.                                                             $mode_change_sign == $sign;
  784.                                                             $mode_changes = ($sign ? '+' : '-') . 'v';
  785.                                                         }
  786.                                                         $mode_change_args[] = $found['nick'];
  787.                                                         if($sign && !in_array($found, $channel['voiced']))
  788.                                                         {
  789.                                                             $channel['voiced'][] = $found;
  790.                                                         }
  791.                                                         if(!$sign && in_array($found, $channel['voiced']))
  792.                                                         {
  793.                                                             $this->nick_removal($found['nick'], $channel['voiced']);
  794.                                                         }
  795.                                                     }
  796.                                                 break;
  797.                                             }
  798.                                         }
  799.  
  800.                                         /* $message = substr($c, strpos($c, ' :') + 2);
  801.                                           $channel['topic'] = $message;
  802.                                           $channel['topic_time'] = time();
  803.                                           $channel['topic_who'] = $me['nick']; */
  804.                                         if($mode_changes != '')
  805.                                         {
  806.                                             foreach($channel['nicks'] as $user)
  807.                                             {
  808.                                                 $this->send($user, ':' . $this->confArr['hostname'] . ' MODE ' . $target . ' ' . $mode_changes . ' ' . implode(' ', $mode_change_args));
  809.                                             }
  810.                                             $this->chanArr[strtolower($target)] = $channel;
  811.                                         }
  812.                                     }
  813.                                 }
  814.                                 else
  815.                                 { // No such channel (nick mdoes are not coded for yet)
  816.                                     $this->send($me, ':' . $this->confArr['hostname'] . ' 403 ' . $me['nick'] . ' ' . $target . ' :No such channel');
  817.                                 }
  818.                             }
  819.                             else
  820.                             {
  821.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 461 ' . $me['nick'] . ' SAMODE :Not enough parameters');
  822.                             }
  823.                         }
  824.                         else
  825.                         {
  826.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 481 ' . $me['nick'] . ' :Permission Denied- You do not have the correct IRC operator privileges');
  827.                         }
  828.                     break;
  829.                    
  830.                     case 'QUIT': // Nice and simple due to the kill() function. FUNCTIONS FTW!
  831.                         $message = 'Client exited';
  832.                         if(strpos($c, ' :') !== false)
  833.                         {
  834.                             $message = 'Quit: ' . substr($c, strpos($c, ' :') + 2);
  835.                         }
  836.                         foreach($this->operArr as $oper)
  837.                         {
  838.                             if(isset($this->operArr[$me['nick']]))
  839.                             {
  840.                                 unset($this->operArr[$me['nick']]);
  841.                             }
  842.                         }
  843.                         $this->kill($me, $message);
  844.                     break;
  845.  
  846.                     case 'USERHOST': // Return user's hostname.
  847.                         $this->send($me, ':' . $this->confArr['hostname'] . ' 302 ' . $me['nick'] . ' :' . $me['nick'] . '=+' . $me['ident'] . '@' . $me['host']);
  848.                     break;
  849.                    
  850.                     case 'PART': // TODO: Code lists (#a,#b,#c)
  851.                         $target = $args[1];
  852.                         $message = '';
  853.                        
  854.                         if(strpos($c, ' :') !== false)
  855.                         {
  856.                             $message = substr($c, strpos($c, ' :'));
  857.                         }
  858.                        
  859.                         // O RLY? (Does the channel even exist?)
  860.                         if(isset($this->chanArr[strtolower($target)]))
  861.                         { // YA RLY
  862.                             $channel = $this->chanArr[strtolower($target)];
  863.                             if(!in_array($me, $channel['nicks']))
  864.                             { // Make sure the user is there....
  865.                                 $this->send($me, ':' . $this->confArr['hostname'] . ' 442 ' . $me['nick'] . ' ' . $target . ' :You\'re not on that channel');
  866.                                 break;
  867.                             }
  868.  
  869.                             foreach($channel['nicks'] as $user)
  870.                             { // Tell everyone about the part! But not about the whole.
  871.                                 $this->send($user, ':' . $me['nick'] . '!' . $me['ident'] . '@' . $this->userArr[(int)$me['sock']]['cloak'] . ' PART ' . $target . $message);
  872.                             }
  873.                         }
  874.                         else
  875.                         { // NO RLY
  876.                             $this->send($me, ':' . $this->confArr['hostname'] . ' 403 ' . $me['nick'] . ' ' . $target . ' :No such channel');
  877.                             break;
  878.                         }
  879.  
  880.                         // Remove from channel listings. We need to search all the modes arrays too.
  881.                         $arrs = array('nicks', 'owners', 'protected', 'oped', 'halfoped', 'voiced');
  882.                        
  883.                         foreach($arrs as $arr)
  884.                         {
  885.                             $this->nick_removal($me['nick'], $channel[$arr]);
  886.                         }
  887.  
  888.                         $this->chanArr[strtolower($target)] = $channel; // Might not be needed if I used a & up there ^^ but who cares?
  889.                     break;
  890.                    
  891.                     case 'NAMES':
  892.                         $target = $args[1];
  893.                         $names = '';
  894.                         if(isset($this->chanArr[strtolower($target)]))
  895.                         { // If channel exists....
  896.                             $channel = $this->chanArr[strtolower($target)];
  897.                             foreach ($channel['nicks'] as $user)
  898.                             { // Build list.
  899.                                 $chars = '';
  900.                                 $search = array('~' => 'owners', '&' => 'owners', '@' => 'oped', '%' => 'halfoped', '+' => 'voiced');
  901.                                 foreach($search as $search_char => $search_name)
  902.                                 {
  903.                                     if(in_array($user, $channel[$search_name]))
  904.                                     {
  905.                                         $chars .= $search_char;
  906.                                     }
  907.                                 }
  908.                                 $names .= $chars . $user['nick'] . ' ';
  909.                             }
  910.                         }
  911.                        
  912.                         $this->send($me, ':' . $this->confArr['hostname'] . ' 353 ' . $me['nick'] . ' = ' . $target . ' :' . $names);
  913.                         $this->send($me, ':' . $this->confArr['hostname'] . ' 366 ' . $me['nick'] . ' ' . $target . ' :End of /NAMES list.');
  914.                     break;
  915.                    
  916.                     case 'LIST':
  917.                         foreach($this->chanArr as $chan => $chanArr)
  918.                         {
  919.                             echo "$chan\r\n";
  920.                         }
  921.                     break;
  922.                    
  923.                     case 'PING': // PONG DAMNIT!
  924.                         if (strpos($args[1], ':') === false)
  925.                         {
  926.                             $args[1] = ':' . $args[1];
  927.                         }
  928.                         $this->send($me, ':' . $this->confArr['hostname'] . ' PONG ' . $this->confArr['hostname'] . ' ' . $args[1]);
  929.                     break;
  930.                 } // Switch
  931.             } // While
  932.         } // Foreach
  933.         sleep(1);
  934.     }
  935.    
  936.     // Validates a nick using regex (also controls max nick length)
  937.     private function validate_nick($nick)
  938.     {
  939.         return preg_match('/^[a-zA-Z\[\]_|`^][a-zA-Z0-9\[\]_|`^]{0,29}$/', $nick);
  940.     }
  941.  
  942.     // Validates a channel name using regex (also controls max channel length)
  943.     private function validate_chan($chan)
  944.     {
  945.         return preg_match('/^#[a-zA-Z0-9`~!@#$%^&*\(\)\'";|}{\]\[.<>?]{0,29}$/', $chan);
  946.     }
  947.    
  948.     // Send a packet to a user and log to console
  949.     private function send($who, $text)
  950.     {
  951.         socket_write($who['sock'], $text . "\r\n");
  952.         echo $who['nick'] . ' >>> ' . $text . "\r\n";
  953.     }
  954.  
  955.     // Removes a value from array, thanks to duck for providing this function
  956.     private function array_removal($val, &$arr)
  957.     {
  958.         $i = array_search($val, $arr);
  959.         if($i === false)   
  960.         {
  961.             return false;
  962.         }
  963.         $arr = array_merge(array_slice($arr, 0, $i), array_slice($arr, $i + 1));
  964.         return true;
  965.     }
  966.  
  967.     // Removes a client with a certian nick from an array of clients, using array_removal
  968.     private function nick_removal($nick, &$arr)
  969.     {
  970.         foreach($arr as $id => $him)
  971.         {
  972.             if(strtolower($him['nick']) == strtolower($nick))
  973.             {
  974.                 return $this->array_removal($him, $arr);
  975.             }
  976.         }
  977.     }
  978.  
  979.     // Kills a certian user, used by /kill, QUIT, netsplits, etc.
  980.     private function kill($who, $reason)
  981.     {  
  982.         $sentto = array($who); // Who received a QUIT packet already?
  983.        
  984.         foreach($this->chanArr as &$channel)
  985.         { // Loop through channels
  986.             if(in_array($who, $channel['nicks']))
  987.             { // Was user x in this channel?
  988.                 foreach($channel['nicks'] as $user)
  989.                 { // Loop through channel nick list
  990.                     if(!in_array($user, $sentto))
  991.                     { // Make sure user didn't get QUIT yet
  992.                         $this->send($user, ':' . $who['nick'] . '!' . $who['ident'] . '@' . $this->userArr[(int)$who['sock']]['cloak'] . ' QUIT :' . $reason);
  993.                         $sentto[] = $user;
  994.                     }
  995.                 }
  996.                 $this->nick_removal($who['nick'], $channel['nicks']); // Remove the killed user from the channel
  997.             }
  998.         }
  999.        
  1000.         $this->send($who, 'ERROR :Closing Link: ' . $who['nick'] . '[' . $who['host'] . '] (' . $reason . ')');
  1001.         socket_close($who['sock']); // Close socket
  1002.        
  1003.         $this->array_removal(@$this->userArr[(int)$who['sock']], $this->userArr); // Remove from the info array - part of the bugfix stated above
  1004.         $this->array_removal($who, $this->connArr); // Remove socket from listing
  1005.     }
  1006.    
  1007.     private function dns_timeout($ip)
  1008.     {
  1009.         $res = `nslookup -timeout=3 -retry=1 $ip`;
  1010.         if(preg_match('/\nName:(.*)\n/', $res, $out))
  1011.         {
  1012.             return trim($out[1]);
  1013.         }
  1014.         else
  1015.         {
  1016.             return $ip;
  1017.         }
  1018.     }
  1019.    
  1020.     private function socket_normal_read($socket)
  1021.     {
  1022.         for($i = 0; isset($this->sockArr[$i]) && $socket != $this->sockArr[$i]; $i++);
  1023.  
  1024.         if(!isset($this->sockArr[$i]))
  1025.         {
  1026.             $this->sockArr[$this->sockNum] = $socket;
  1027.             $this->quesArr [$this->sockNum++] = "";
  1028.         }
  1029.  
  1030.         $recv = @socket_read($socket, $this->confArr['maxlen']);
  1031.         //$recv = str_replace($recv, "\r", "");
  1032.        
  1033.         if($recv === '')
  1034.         {
  1035.             if(strpos($this->quesArr[$i], "\n") === false)
  1036.             {
  1037.                 return false;
  1038.             }    
  1039.         }
  1040.         elseif($recv !== false)
  1041.         {
  1042.             $this->quesArr[$i] .= $recv;
  1043.         }
  1044.  
  1045.         $pos = strpos($this->quesArr[$i], "\n");
  1046.        
  1047.         if($pos === false)
  1048.         {
  1049.             return;
  1050.         }
  1051.        
  1052.         $ret = substr($this->quesArr[$i], 0, $pos);
  1053.         $this->quesArr[$i] = substr($this->quesArr[$i], $pos + 1);
  1054.  
  1055.         return $ret;
  1056.     }
  1057. }
Advertisement
Add Comment
Please, Sign In to add comment