x2Fusion

PHP IRC Snoop/Relay Bot

Sep 9th, 2015
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.53 KB | None | 0 0
  1. <?php
  2.  
  3. /** PHP IRC Snoop/Relay Bot **
  4.  *
  5.  *  ####TODO: Think and then some..
  6.  *  ####TODO: THINK of extras.
  7.  */
  8.  
  9. $sbot = SnoopBot::getInst();
  10.  
  11. $sbot->config = array(
  12.         'mode'      => 'relay',       /// SNOOP OR RELAY
  13.         'serv'      => 'localhost',
  14.         'port'      => 6667,
  15.         'nick'      => 'Nickeroo',
  16.         'name'      => 'MrRooo',
  17.         'chan'      => array('#chan'),
  18.         'nick_ignore'=> array('nigger')
  19.         );
  20.  
  21. $sbot->Init();
  22.  
  23. ###########################################################
  24. class SnoopBot
  25. {  
  26.     private $is_CLI = false;
  27.     private $socket = null;
  28.     private $ex     = null;
  29.     private $tstamp = '0000-00-00 00:00:00';
  30.    
  31.     private $nicks  = array();
  32.     private $chans  = array();
  33.    
  34.     private $curruser = null;
  35.     private $currchan = null;
  36.     private $lastchan = null;
  37.    
  38.     private $userwhois = null;
  39.        
  40.     public $config  = array(
  41.         'mode'          => 'snoop',             # Bot Mode Snoop OR Relay
  42.         'serv'          => 'please.change.me',  # Bot Serv
  43.         'port'          => 6667,                # Bot Port
  44.         'nick'          => 'sbot',              # Bot Nick
  45.         'name'          => 'RelayBot',          # Bot Name
  46.         'chan'          => array('#chan1'),     # Chan to join
  47.         'nick_ignore'   => array('nigger')      # Nicks to Ignore
  48.         );
  49.    
  50.     public static function getInst()
  51.     {
  52.         static $inst = null;
  53.         if ($inst === null)
  54.         {
  55.             $inst = new self;
  56.         }
  57.         return $inst;
  58.     }
  59.    
  60.     // Initital functions
  61.     public function init()
  62.     {      
  63.         // Start connection to IRC
  64.         $this->socket = fsockopen($this->config['serv'], $this->config['port']);
  65.        
  66.         // Send USER/NICK to IRC
  67.         $this->sendData('USER', "{$this->config['nick']} irc.land {$this->config['nick']} :{$this->config['name']}\r\n");
  68.         $this->sendData('NICK', "{$this->config['nick']}\r\n");
  69.        
  70.         while(true)
  71.         {
  72.             // Timestamps
  73.             $this->tstamp = (new \DateTime())->format('H:i:s');
  74.             // Bot Core
  75.             $this->ex = $this->recvData();
  76.            
  77.             // Play Ping-Pong
  78.             if($this->ex[0] == 'PING')
  79.             {
  80.                 $this->sendData('PONG', "{$this->ex[1]}");
  81.             }
  82.            
  83.             // Set Current User/Chan
  84.             $this->curruser = substr(explode('!', $this->ex[0])[0], 1);
  85.             $this->currfunc = @$this->ex[1];
  86.             $this->currchan = @$this->ex[2];
  87.            
  88.             // Switch Functions
  89.             $this->preSwitches();  
  90.            
  91.             if($this->config['mode'] == 'relay')
  92.             {
  93.                 $this->doRelay();
  94.             }
  95.             $this->lastchan = $this->currchan;
  96.         } // While(true)
  97.     }
  98.    
  99.     // Initital Core functions
  100.     private function preSwitches()
  101.     {
  102.         // preSwitches include Pre commands, and post nick/join/kick/part/quit
  103.         switch(@$this->ex[1])
  104.         {
  105.             case '001':  // Check for time to join
  106.                 if(is_array($this->config['chan']))
  107.                 {
  108.                     foreach($this->config['chan'] as $chan)
  109.                     {
  110.                         $this->sendData('JOIN', "$chan\r\n");
  111.                     }
  112.                 }
  113.                 else
  114.                 {
  115.                     $this->sendData('JOIN', "{$this->config['chan']}\r\n");
  116.                 }
  117.             break;
  118.             #####################
  119.             case '311': // Fetch Whois Info
  120.                 $ex = $this->ex;
  121.                 unset($ex[0], $ex[1], $ex[2], $ex[6], $ex[7]);
  122.                 $this->userwhois = $ex;
  123.             break;
  124.             #####################
  125.             case '353': // Fetch Nicks from Channel
  126.                 $ex = $this->ex;
  127.                 $chan = $ex[4];
  128.                 unset($ex[0], $ex[1], $ex[2], $ex[3], $ex[4]);
  129.                 $nicks = implode(' ', $ex);
  130.                 $nicks = str_replace(':', '', $nicks);
  131.                 $nicks = str_replace('@', '', $nicks);
  132.                 $this->nicks[$chan] = explode(' ', ucwords($nicks));
  133.             break;
  134.             #####################
  135.             case '433': // Set random nick, if Nick inuse
  136.                 $randId = substr(mt_rand(), 0, strlen(mt_rand())/2);
  137.                 $this->sendData('NICK', "{$this->config['nick']}$randId\r\n");
  138.             break;
  139.             #####################
  140.             case 'NICK': // Update Nicks array on Nick Change
  141.                 $olduser = trim(ucwords(str_replace(':', '', explode("!", substr($this->ex[0], 1))[0])));
  142.                 $newuser = trim(ucwords($this->ex[2]));
  143.                 if($olduser == ucwords($this->config['nick']))
  144.                 {
  145.                     $this->sendData('NICK', "{$this->config['nick']}\r\n");
  146.                 }
  147.                 foreach($this->chans as $chan)
  148.                 {
  149.                     foreach($this->nicks[$chan] as $nickId => $nick)
  150.                     {
  151.                         if($olduser == $nick)
  152.                         {
  153.                             $this->nicks[$chan][$nickId] = $newuser;
  154.                         }
  155.                     }
  156.                 }
  157.             break;
  158.             #####################
  159.             case 'PRIVMSG':
  160.                 //echo "PRIVMSG\r\n";
  161.                 if($this->config['mode'] == 'snoop')
  162.                 {
  163.                     $user = substr(explode('!', $this->ex[0])[0], 1);
  164.                     if(!in_array($user, $this->config['nick_ignore']))
  165.                     {
  166.                         $this->doSnoop('PRIVMSG');
  167.                     }
  168.                 }
  169.                 else
  170.                 {
  171.                     $this->doRelay();
  172.                 }
  173.             break;
  174.             #####################
  175.             case 'JOIN':
  176.                 if($this->config['mode'] == 'snoop')
  177.                 {
  178.                     $this->doSnoop('JOIN');
  179.                 }
  180.                 $chan = trim(strtolower(substr($this->ex[2], 1)));
  181.                 $user = trim(ucwords(explode("!", substr($this->ex[0], 1))[0]));
  182.                 $this->chans[$chan] = $chan;
  183.                 $this->nicks[$chan][] = $user;
  184.             break;
  185.             #####################
  186.             case 'KICK':
  187.                 if($this->config['mode'] == 'snoop')
  188.                 {
  189.                     $this->doSnoop('PRIVMSG');
  190.                 }
  191.                 $this->sendData('JOIN', "{$this->ex[2]}\r\n");
  192.             break;
  193.             #####################
  194.             case 'PART':
  195.                 if($this->config['mode'] == 'snoop')
  196.                 {
  197.                     $this->doSnoop('PART');
  198.                 }
  199.                 $olduser = trim(ucwords(str_replace(':', '', explode("!", substr($this->ex[0], 1))[0])));
  200.                 $this->currchan = trim($this->currchan);
  201.                 foreach($this->nicks[$this->currchan] as $nickId => $nick)
  202.                 {
  203.                     if($olduser == $nick)
  204.                     {
  205.                         unset($this->nicks[$this->currchan][$nickId]);
  206.                     }
  207.                 }
  208.             break;
  209.             #####################
  210.             case 'QUIT':
  211.                 if($this->config['mode'] == 'snoop')
  212.                 {
  213.                     $this->doSnoop('QUIT');
  214.                 }
  215.                 $olduser = trim(ucwords(str_replace(':', '', explode("!", substr($this->ex[0], 1))[0])));
  216.                 foreach($this->chans as $chan)
  217.                 {
  218.                     foreach($this->nicks[$chan] as $nickId => $nick)
  219.                     {
  220.                         if($olduser == $nick)
  221.                         {
  222.                             unset($this->nicks[$chan][$nickId]);
  223.                         }
  224.                     }
  225.                 }
  226.             break;
  227.         }
  228.     }
  229.    
  230.     private function doSnoop($func = 'PRIVMSG')
  231.     {
  232.         //echo "SNOOP\r\n";
  233.         $ex = $this->ex;
  234.         switch($func)
  235.         {
  236.             case 'JOIN':
  237.                 unset($ex[0]);
  238.                 $this->currchan = trim(substr($this->currchan, 1));
  239.             break;
  240.             case 'PART':
  241.                 unset($ex[0]);
  242.             break;
  243.             case 'QUIT':
  244.                 unset($ex[0]);
  245.                 $this->currchan = $this->lastchan;
  246.             break;
  247.             case 'PRIVMSG':
  248.                 unset($ex[0], $ex[1], $ex[2]);
  249.             break;
  250.         }
  251.         $this->writeLog(implode(" ", $ex), $this->currchan);
  252.     }
  253.    
  254.     private function doRelay()
  255.     {
  256.         //echo "RELAY\r\n";
  257.         foreach($this->chans as $chan)
  258.         {
  259.             if(file_exists("xferchans/$chan"))
  260.             {
  261.                 $data = trim(file_get_contents("xferchans/$chan"));
  262.                 foreach(explode("\n", $data) as $line)
  263.                 {
  264.                     //echo "$line\r\n";
  265.                     $this->sendData("PRIVMSG $chan :", "$line\r\n");
  266.                 }
  267.                 unlink("xferchans/$chan");
  268.             }
  269.         }
  270.     }
  271.    
  272.     // Send/Recv/Log Functions
  273.     private function sendData($command, $message = null)
  274.     {
  275.         echo 'SND-MSG: ';
  276.         if($message == null)
  277.         {
  278.             echo "$command" . PHP_EOL;
  279.             fputs($this->socket, (string)"$command\r\n");
  280.         }
  281.         else
  282.         {
  283.             echo "$command -> $message" . PHP_EOL;
  284.             fputs($this->socket, (string)"$command $message\r\n");
  285.         }
  286.     }
  287.    
  288.     private function recvData()
  289.     {
  290.         $data = fgets($this->socket, 1024);
  291.         if($data != '')
  292.         {
  293.             echo "RCV-MSG: $data" . PHP_EOL;
  294.         }
  295.         return explode(' ', $data);
  296.     }
  297.    
  298.     private function writeLog($input = null, $chan = null)
  299.     {
  300.         $input = trim($input);
  301.         $user = substr(explode('!', $this->ex[0])[0], 1);
  302.         echo "SYS-MSG: Append Log: $chan -> <$user> $input" . PHP_EOL . PHP_EOL;
  303.         file_put_contents("xferchans/$chan", (string)"4,0{$this->tstamp} {$this->config['serv']}:{$this->config['port']} -> <$user> $input" . PHP_EOL, FILE_APPEND);
  304.     }
  305. }
Advertisement
Add Comment
Please, Sign In to add comment