phpDocumentor phpIcqBot
[ class tree: phpIcqBot ] [ index: phpIcqBot ] [ all elements ]

Source for file kernel.class.php

Documentation is available at kernel.class.php

  1. <?php
  2.  
  3. define('VER''phpIcqBot v0.1 alpha');
  4.  
  5. define('ICQBOT_EVENT_RESTART','Restart');
  6. define('ICQBOT_EVENT_CONNECT','Connect');
  7. define('ICQBOT_EVENT_DISCONNECT','Disconnect');
  8. define('ICQBOT_EVENT_COMMAND','Command');
  9.  
  10. require_once './libs/WebIcqPro.class.php';
  11.  
  12. require_once './kernel/commands.class.php';
  13. require_once './kernel/logs.class.php';
  14. require_once './kernel/modules.class.php';
  15. require_once './kernel/store.class.php';
  16. require_once './kernel/store/store.flatfile.class.php';
  17. require_once './kernel/users.class.php';
  18.  
  19. class IcqBot {
  20.  
  21.     /**
  22.      * WebIcqPro class
  23.      *
  24.      * @var WebIcqPro 
  25.      */
  26.     public $proto;
  27.  
  28.     public  $uin;
  29.     private $pwd;
  30.  
  31.     public $status;
  32.     
  33.     /**
  34.      * Shows if phpIcqBot is working
  35.      *
  36.      * @var bool 
  37.      */
  38.     public $working;
  39.  
  40.     /**
  41.      * IcqBot_Commands
  42.      *
  43.      * @var IcqBot_Commands 
  44.      */
  45.     private $comm;
  46.     
  47.  
  48.     /**
  49.      * Log class...
  50.      *
  51.      * @var IcqBot_Logs 
  52.      */
  53.     private $logs;
  54.  
  55.     
  56.     private $terminating false;
  57.     
  58.     /**
  59.      * Variable, if need to do restart
  60.      *
  61.      * @var bool 
  62.      */
  63.     private $restart false;
  64.     
  65.     /**
  66.      * Current configuration (modules, commands, etc)
  67.      *
  68.      * @var IcqBot_Conf 
  69.      */
  70.     private $conf;
  71.     
  72.     
  73.     public function __construct()
  74.     {
  75.         date_default_timezone_set('Asia/Yekaterinburg');
  76.         
  77.         if (file_exists('./config.inc.php'))
  78.         {
  79.             require_once('./config.inc.php');
  80.         }
  81.         
  82.         if (!defined('UIN'))
  83.         {
  84.             require './kernel/install.class.php';
  85.             $install new IcqBot_Install();
  86.             if ($this->terminating $install->work())
  87.             {
  88.                 return;
  89.             }
  90.             
  91.             if (file_exists('./config.inc.php'))
  92.             {
  93.                 require_once('./config.inc.php');
  94.             }
  95.             
  96.             if (!defined('UIN'))
  97.             {
  98.                 $this->terminating true;
  99.                 echo "Some pity error.. Check permissions to write config.inc.php file.";
  100.                 return;
  101.             }
  102.         }
  103.         
  104.         $this->init();
  105.         
  106.         //register_shutdown_function(array(&$this, "terminate"));
  107.         set_error_handler(array(&$this'errHandler'));
  108.     }
  109.  
  110.     public function connect($uin ''$pwd '')
  111.     {
  112.         if ($this->terminating)
  113.         {
  114.             return;
  115.         }
  116.  
  117.         if ($uin)
  118.         {
  119.         
  120.             $this->uin = $uin;
  121.             $this->pwd $pwd;
  122.         }
  123.         else
  124.         {
  125.             $this->uin = UIN;
  126.             $this->pwd PASSWORD;
  127.         }
  128.  
  129.         $this->logs->write('Connecting to ICQ server with UIN: '.$this->uin.', PWD: '.str_repeat('*',strlen($this->pwd)));
  130.         $result $this->proto->connect($this->uin$this->pwd);
  131.  
  132.         if (!$result)
  133.         {
  134.             $this->logs->write('ICQ ERROR: '.$this->proto->error);
  135.             exit($this->proto->error);
  136.         }
  137.  
  138.         $this->logs->write('Connected.');
  139.         $this->raiseEvent(ICQBOT_EVENT_CONNECT);
  140.         $this->comm->setStatus(STARTSTATUS);
  141.         return;
  142.     }
  143.  
  144.     public function work()
  145.     {
  146.         if ($this->terminating)
  147.         {
  148.             return;
  149.         }
  150.  
  151.         $this->connect();
  152.             
  153.         $this->logs->write('Starting working cycle...');
  154.         $this->working = true;
  155.  
  156.         while($this->proto->isConnected(&& $this->working)
  157.         {
  158.             $this->logs->write('Working cycle.',LOGLEVEL_5);
  159.             $this->action($this->proto->readMessage());
  160.             flush();
  161.             $this->queue();
  162.             $this->cron();
  163.             sleep(1);
  164.             if ($this->restart)
  165.             {
  166.                 $this->do_restart();
  167.             }
  168.         }
  169.         $this->logs->write('Working cycle finished.');
  170.         $this->deinit();
  171.     }
  172.  
  173.     public function action($msg)
  174.     {
  175.         if (!isset($msg['from']|| !isset($msg['message']))
  176.         {
  177.             return false;
  178.         }
  179.  
  180.         if (LOGLEVEL>=LOGLEVEL_4)
  181.         {
  182.             $this->logs->write('MSG: '.str_replace("\r"," ",str_replace("\n"," ",(print_r($msg,true)))),LOGLEVEL_4);
  183.         }
  184.  
  185.         IcqBot_Users::load($msg['from'])->updateAccess();
  186.  
  187.         if (substr($msg['message'],0,1== CMD_PREF)
  188.         {
  189.             return $this->cmd($msg['from']substr($msg['message'],1));
  190.         }
  191.         $this->logs->write('Unknown command from '.$msg['from'],LOGLEVEL_3);
  192.         return $this->comm->sendMsg($msg['from'],"Unknown command. Send ".CMD_PREF."help");
  193.     }
  194.  
  195.     public function cmd($uin$cmd)
  196.     {
  197.         if (strpos($cmd," "!== false)
  198.         {
  199.             list($cmd$paramsexplode(" ",$cmd,2);
  200.         }
  201.         else
  202.         {
  203.             $params '';
  204.         }
  205.  
  206.         $this->logs->write("Cmd$cmdUin$uin",LOGLEVEL_3);
  207.         $this->commandModules($uin$cmdtrim($params));
  208.     }
  209.     
  210.     public function queue()
  211.     {
  212.         if (!($msg array_shift($this->conf->msg_queue)))
  213.         {
  214.             return;
  215.         }
  216.         $this->proto->sendMessage($msg[0],$msg[1]);        
  217.     }
  218.  
  219.     public function logout($break false)
  220.     {
  221.         $this->logs->write('Logging out.'.($break?' Break called.':''));
  222.         $this->proto->disconnect();
  223.     }
  224.     
  225.     private function loadModules()
  226.     {
  227.         $modulesList glob('./modules/*.module.php');
  228.         $cnt 0;
  229.         $included_files get_included_files();
  230.         foreach ($included_files as $n=>$f)
  231.         {
  232.             $included_files[$n]=basename($f);
  233.         }
  234.         
  235.         if ($modulesList!==FALSE)
  236.         {
  237.             foreach ($modulesList as $module)
  238.             {
  239.                 if ($this->loadModule($module$included_files=== true)
  240.                 {
  241.                     $cnt++;
  242.                 }
  243.             }
  244.         }
  245.  
  246.         return $cnt;        
  247.     }
  248.     
  249.     public function loadModule($moduleName&$included_files)
  250.     {
  251.         $m   false;
  252.         if (!preg_match('/([a-z0-9_]+)\.module\.php$/i',$moduleName,$m))
  253.         {
  254.             return false;
  255.         }
  256.         $this->logs->write("Loading module: ".$m[1].".module");
  257.  
  258.         if (!in_array($m[1].'.module.php'$included_files))
  259.         {
  260.             $this->logs->write('File "'.$moduleName.'" is not included. Including...');
  261.             if (!file_exists('./modules/'.$m[1].'.module.php'))
  262.             {
  263.                 $this->logs->write('ERROR: file "'.$moduleName.'" doesn\'t exists');
  264.                 return 'ERROR: file "'.$moduleName.'" doesn\'t exists';
  265.             }
  266.             require './modules/'.$m[1].'.module.php';
  267.         }
  268.  
  269.         $mod_name 'IcqBot_Module_'.ucfirst(strtolower($m[1]));
  270.         if (!class_exists($mod_name))
  271.         {
  272.             $this->logs->write('ERROR: class "'.$mod_name.'" not found in "'.$moduleName.'".');
  273.             return 'ERROR: class "'.$mod_name.'" not found in "'.$moduleName.'".';
  274.         }
  275.         
  276.         if (!is_subclass_of($mod_name"IcqBot_Module"))
  277.         {
  278.             $this->logs->write('ERROR: class "'.$mod_name.'" is not child of IcqBot_Module class.');
  279.             return 'ERROR: class "'.$mod_name.'" is not child of IcqBot_Module class.';
  280.         }
  281.         
  282.         if (key_exists($mod_name$this->conf->modules))
  283.         {
  284.             $this->logs->write('ERROR: module "'.$mod_name.'" is already loaded.');
  285.             return 'ERROR: module "'.$mod_name.'" is already loaded.';
  286.         }
  287.         
  288.         /** @var $mod IcqBot_Module **/
  289.         $this->conf->modules[$mod_namearray("iface" => ($mod new $mod_name ($this->comm$this->logs))"Commands"=>0"Aliases"=>0);
  290.         if (is_subclass_of($mod"IcqBot_ModuleAdmin"))
  291.         {
  292.             $mod->setIcqBot($this,$this->conf,$this->proto);
  293.         }
  294.         
  295.         $mod->init();
  296.         $this->logs->write('Module "'.$m[1].'.module" loaded. Commands: '.$this->conf->modules[$mod_name]['Commands'].' '.
  297.                                                              'Aliases: '.$this->conf->modules[$mod_name]['Aliases'].' ');
  298.         return true;
  299.     }
  300.     
  301.     private function commandModules($uin$cmd$params)
  302.     {
  303.         if (!array_key_exists($cmd$this->conf->commands))
  304.         {
  305.             return false;
  306.         }
  307.         
  308.         $this->raiseEvent(ICQBOT_EVENT_COMMAND);
  309.         
  310.         return call_user_func_array($this->conf->commands[$cmd]array($uin$params));
  311.     }
  312.  
  313.     public function terminate()
  314.     {
  315.         $this->logs->write('Error occurs... TERMINATING...');
  316.         $this->working = false;
  317.         $this->deinit();
  318.     }
  319.     
  320.     public function errHandler($errno$errstr$errfile$errline)
  321.     {
  322.         $err "PHP ERROR $errstr ($errno in $errfile on $errline line)";
  323.         $this->logs->write($errLOGLEVEL_0'[r]''error.log');
  324.     }
  325.     
  326.     public function restart()
  327.     {
  328.         $this->restart=true;
  329.         $this->raiseEvent(ICQBOT_EVENT_RESTART);
  330.     }
  331.     
  332.     private function do_restart()
  333.     {
  334.         $this->logs->write('Restarting...');
  335.  
  336.         $this->deinit();
  337.         
  338.         $this->restart false;
  339.         
  340.         $this->init(true);
  341.         $this->connect();
  342.         $this->logs->write('Restart complete...');
  343.     }
  344.     
  345.     private function init($restart false)
  346.     {
  347.         $this->proto = new WebIcqPro();
  348.  
  349.         $this->proto->setOption('UserAgent''miranda');
  350.  
  351.         $this->logs new IcqBot_Logs();
  352.         if (!$restart)
  353.         {
  354.             $this->logs->write("IcqBot started.");
  355.         }
  356.         else 
  357.         {
  358.             $this->logs->write("IcqBot restarted.");
  359.         }
  360.         $this->logs->write("Loading modules...");
  361.         
  362.         $this->conf new IcqBot_Conf();
  363.         $this->conf->store = new IcqBot_Store_Flatfile($this->logs);
  364.  
  365.         $this->comm new IcqBot_Commands($this$this->conf$this->proto$this->logs);
  366.         
  367.         $totalLoaded $this->loadModules();
  368.         $this->logs->write('Total modules loaded: '.$totalLoaded);
  369.     }
  370.  
  371.     private function deinit()
  372.     {
  373.         $this->logs->write('Unloading modules...');
  374.         foreach($this->conf->modules as $mod_name=>$module)
  375.         {
  376.             $this->conf->modules[$mod_name]['iface']->deinit();
  377.             unset($this->conf->modules[$mod_name]['iface']);
  378.             unset($this->conf->modules[$mod_name]);
  379.         }
  380.         
  381.         unset($this->conf->store);
  382.         unset($this->conf);
  383.  
  384.         $this->logs->write('Disconnecting...');
  385.         $this->proto->disconnect();
  386.         $this->raiseEvent(ICQBOT_EVENT_DISCONNECT);
  387.  
  388.         $this->logs->write('Unloading users...');
  389.         IcqBot_Users::saveAll();
  390.         IcqBot_Users::flushAll();
  391.         
  392.         $this->logs->write('Unloading classes...');
  393.         unset($this->proto);
  394.         unset($this->comm);
  395.         $this->logs->write('Finished...');
  396.         unset($this->logs);
  397.     }
  398.     
  399.     public function raiseEvent($event)
  400.     {
  401.         $i=0;
  402.         if (!isset($this->conf->events[ICQBOT_EVENT_RESTART]))
  403.         {
  404.             return 0;
  405.         }
  406.         
  407.         foreach ($this->conf->events[ICQBOT_EVENT_RESTARTas $module)
  408.         {
  409.             call_user_func(array(&$module,"Event_".$event));
  410.             $i++;
  411.         }
  412.         return $i;
  413.     }
  414.     
  415.     public function cron()
  416.     {
  417.         $t time();
  418.         foreach ($this->conf->cron as $mod=>$ctime)
  419.         {
  420.             if ($ctime<=$t)
  421.             {
  422.                 list($mod_name$keyexplode('@',$mod,2);
  423.                 call_user_func($this->conf->timer[$mod_name][$key]['callback'],$key);
  424.                 $this->conf->cron[$mod]=$t+$this->conf->timer[$mod_name][$key]['interval'];
  425.             }
  426.         }
  427.     }
  428. }
  429.  
  430. {
  431.     /**
  432.      * Array of loaded modules
  433.      *
  434.      * @var array 
  435.      */
  436.     public $modules = array();
  437.     
  438.  
  439.     public $commands = array();
  440.  
  441.     /**
  442.      * Outbound message queue
  443.      *
  444.      * @var array (to, msg)
  445.      */
  446.     public $msg_queue = array();
  447.     
  448.  
  449.     public $cron = array();
  450.     public $timer = array();
  451.  
  452.     public $events = array();
  453.     
  454.  
  455.     /**
  456.      * Storing class
  457.      *
  458.      * @var IcqBot_Store 
  459.      */
  460.     public $store;
  461. }

Documentation generated on Mon, 24 Dec 2007 09:34:30 +0500 by phpDocumentor 1.4.0