require_once("saxdb.class.php");
class BotLoader {
+ const BOT_DIR = "Bots";
+ const TMP_DIR = "tmp";
private $uplink;
private $saxdb;
private $botdb;
private $loadedBots = array();
+ private $botDatabases = array();
+ private static $botloader;
public function __construct($uplink) {
$this->uplink = $uplink;
$this->saxdb = new saxdb();
$this->saxdb->loadDB("php_p10.db");
$this->botdb = $this->saxdb->getSection("BotLoader");
+ self::$botloader = $this;
+ timer(60*10, array($this, "autosave"), array());
}
public function loadBots() {
}
}
+ public function unloadBots() {
+ foreach($this->loadedBots as $name => $bot) {
+ $this->unloadBot($name, false);
+ }
+ }
+
+ public function save() {
+ $this->saxdb->writeDB("php_p10.db");
+ }
+
+ public function autosave() {
+ foreach($this->loadedBots as $name => $bot) {
+ if(array_key_exists(strtolower($name), $this->botDatabases)) {
+ $db = $bot->writeDB();
+ $this->saxdb->setSection($this->botDatabases[strtolower($name)],$db);
+ }
+ }
+ $this->save();
+ timer(60*10, array($this, "autosave"), array());
+ }
+
+ public function loop() {
+ foreach($this->loadedBots as $name => $bot) {
+ $bot->loop();
+ }
+ }
+
private function loadBot($name, $botfile) {
- if(array_key_exists($name, $this->loadedBots)) return;
+ if(array_key_exists(strtolower($name), $this->loadedBots)) return false;
//load bot
+ $bot = $this->loadClass($botfile, $name);
+ if(!$bot) return false;
+ $bot->load($this->uplink);
+ $this->loadedBots[strtolower($name)] = $bot;
if(!array_key_exists($name, $this->botdb["bots"])) {
$this->botdb["bots"][$name] = $botfile;
}
}
+ private function unloadBot($name, $delete = true) {
+ if(!(array_key_exists(strtolower($name), $this->loadedBots))) return false;
+ //unload bot
+ $bot = $this->loadedBots[strtolower($name)];
+ if(array_key_exists(strtolower($name), $this->botDatabases)) {
+ $db = $bot->writeDB();
+ $this->saxdb->setSection($this->botDatabases[strtolower($name)],$db);
+ unset($this->botDatabases[strtolower($name)]);
+ }
+ ModCMD::unbindBot($bot);
+ $bot->unload(false);
+ unset($this->loadedBots[strtolower($name)]);
+ if(array_key_exists($name, $this->botdb["bots"]) && $delete) {
+ unset($this->botdb["bots"][$name]);
+ }
+ }
+
+ private function rehashBot($name) {
+ if(!(array_key_exists(strtolower($name), $this->loadedBots))) return false;
+ //rehash bot
+ $bot = $this->loadedBots[strtolower($name)];
+ if(array_key_exists(strtolower($name), $this->botDatabases)) {
+ $db = $bot->writeDB();
+ $this->saxdb->setSection($this->botDatabases[strtolower($name)],$db);
+ unset($this->botDatabases[strtolower($name)]);
+ }
+ ModCMD::unbindBot($bot);
+ $data = $bot->unload(true);
+ unset($this->loadedBots[strtolower($name)]);
+ //ok bot is unloaded... load it again...
+ $bot = $this->loadClass($botfile, $name);
+ if(!$bot) return false;
+ $bot->load($this->uplink, $data);
+ $this->loadedBots[strtolower($name)] = $bot;
+ }
+
+ private function listLoadedBots() {
+ return $this->loadedBots;
+ }
+
+ private function addDBsection($bot, $section) {
+ if(!is_a($bot, "Bot")) return false;
+ $name = null;
+ foreach($this->loadedBots as $botname => $cbot) {
+ if($cbot === $bot) {
+ $name = $botname;
+ break;
+ }
+ }
+ if($name == null) return false;
+ if(array_key_exists(strtolower($name), $this->botDatabases)) {
+ return false;
+ }
+ $this->botDatabases[strtolower($name)] = $section;
+ $bot->readDB($this->saxdb->getSection($section));
+ }
+
+ private function loadClass($file, $classprefix) {
+ $dir = self::BOT_DIR;
+ $tmp = self::TMP_DIR;
+ $maincode=file_get_contents($dir."/".$file);
+ if(!$maincode) return;
+ $class = rand(10000,99999);
+ while(class_exists("bot_".$classprefix."_".$class)) {
+ $class = rand(10000,99999);
+ }
+ $maincode = str_replace('{$_NAME}', "module_".$classprefix."_".$class, $maincode);
+ $fp = fopen($tmp."/modules_".$classprefix."_".$class.".tmp.php", 'w');
+ fwrite($fp, $maincode);
+ fclose($fp);
+ include($tmp."/modules_".$classprefix."_".$class.".tmp.php");
+ $classname = "module_".$classprefix."_".$class;
+ $newclass = new $classname();
+ unlink($tmp."/modules_".$classprefix."_".$class.".tmp.php");
+ return $newclass;
+ }
+
+ public static function load($name, $botfile) {
+ return self::$botloader->loadBot($name, $botfile);
+ }
+
+ public static function unload($name) {
+ return self::$botloader->unloadBot($name);
+ }
+
+ public static function rehash($name) {
+ return self::$botloader->rehashBot($name);
+ }
+
+ public static function listBots() {
+ return self::$botloader->listLoadedBots();
+ }
+
+ public static function registerDB($bot, $name) {
+ return self::$botloader->addDBsection($bot, $name);
+ }
}
?>
\ No newline at end of file
}
public function unload($rehash = false) { //this function is triggered, when the Bot is unloaded... If it's just a rehash the return value of this method is passed to $old in the load method.
- return $this->example_bot;
+ if($rehash) {
+ return $this->example_bot;
+ } else {
+ $this->uplink->delUser($this->example_bot, "Bye.");
+ }
}
public function recive_privmsg($user, $channel, $message) {
--- /dev/null
+<?php
+/********************************* PHP-P10 ******************************
+ * P10 uplink class by pk910 (c)2011 pk910 *
+ ************************************************************************
+ * Version 2 (OOP) *
+ * *
+ * PHP-P10 is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with PHP-P10; if not, write to the Free Software Foundation, *
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
+ * *
+ ************************************************************************
+ *
+ * Bots/ModManager.class.php
+ *
+ * module manager bot...
+ *
+ */
+
+class {$_NAME} extends Bot {
+ private $uplink;
+ private $modman;
+
+ public function load($uplink, $old = false) {
+ $this->uplink = $uplink;
+ if(!$old) {
+ $nick = "ModuleMan";
+ $ident = "modman";
+ $host = "Services.WebGamesNet.net";
+ $ip = "0::0";
+ $realname = "Module Manager";
+ $modes = "ioknISD";
+ $this->modman = $this->uplink->addUser($nick,$ident,$host,$ip,$modes,$realname);
+ if(is_a($this->modman, "P10_User")) {
+ $this->uplink->join($this->modman, "#opers", (P10_Channel::USERPRIV_OPED | P10_Channel::USERPRIV_VOICE));
+ $this->uplink->join($this->modman, "#dev", P10_Channel::USERPRIV_VOICE);
+ }
+ } else {
+ $this->modman = $old;
+ }
+
+ ModCMD::bind($this, BIND_PRIVMSG, "recive_privmsg");
+ ModCMD::bind($this, BIND_QUIT, "recive_quit");
+ }
+
+ public function unload($rehash = false) {
+ if($rehash) {
+ return $this->modman;
+ } else {
+ $this->uplink->delUser($this->modman, "Bye.");
+ }
+ }
+
+ function recive_privmsg($user, $channel, $message) {
+ if(!$user->getModes()->hasMode('o')) return 0;
+ $exp=explode(" ",$message);
+ switch (strtolower($exp[0])) {
+ case "~loadmod":
+ if(BotLoader::load($exp[1],$exp[2])) {
+ $this->uplink->privmsg($this->modman, $channel, "done.");
+ } else {
+ $this->uplink->privmsg($this->modman, $channel, "error.");
+ }
+ break;
+ case "~unloadmod":
+ if(BotLoader::unload($exp[1])) {
+ $this->uplink->privmsg($this->modman, $channel, "done.");
+ } else {
+ $this->uplink->privmsg($this->modman, $channel, "error.");
+ }
+ break;
+ case "~rehash":
+ if(BotLoader::rehash($exp[1])) {
+ $this->uplink->privmsg($this->modman, $channel, "done.");
+ } else {
+ $this->uplink->privmsg($this->modman, $channel, "error.");
+ }
+ break;
+ case "~debug":
+ $exp=explode(" ",$message,2);
+ ob_start();
+ $ret = eval($exp[1]);
+ $out = ob_get_contents();
+ ob_end_clean();
+ $lines = explode("\n",$out);
+ for($i=0;$i<count($lines);$i++) {
+ if($lines[$i]!="") {
+ $this->uplink->privmsg($this->modman, $channel, $lines[$i]);
+ }
+ }
+ $lines = explode("\n",$ret);
+ for($i=0;$i<count($lines);$i++) {
+ if($lines[$i]!="") {
+ $this->uplink->privmsg($this->modman, $channel, $lines[$i]);
+ }
+ }
+ break;
+ }
+ }
+
+ function recive_quit($user, $reason) {
+ if($user === $this->modman) {
+ $this->load($this->uplink);
+ }
+ }
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+$timers['id']=0;
+
+function timer_loop() {
+ global $timers;
+ $mtime = microtime(true);
+ $ret = false;
+ foreach ($timers as $id => $timer) {
+ if(($timer['expire'] - 0.00019) <= $mtime) { //we expire a timer 0,19 ms before (to reduce timer desyncs)
+ if((is_array($timer['function']) && method_exists($timer['function'][0],$timer['function'][1])) || (!is_array($timer['function']) && function_exists($timer['function']))) {
+ call_user_func_array($timer['function'],$timer['params']);
+ }
+ $ret = true;
+ unset($timers[$id]);
+ }
+ }
+ return $ret;
+}
+
+function timer($seconds,$command,$parameter) {
+ global $timers;
+ $new['expire'] = microtime(true) + $seconds;
+ $new['function'] = $command;
+ $new['params'] = $parameter;
+ while(isset($timers[$timers['id']])|| !isset($timers['id'])) {
+ $timers['id']++;
+ if($timers['id'] > 9999999) $timers['id'] = 0;
+ }
+ $timers[$timers['id']] = $new;
+ return $timers['id'];
+}
+
+function utimer($seconds,$command,$parameter) {
+ global $timers;
+ $new['expire'] = microtime(true) + ($seconds / 1000);
+ $new['function'] = $command;
+ $new['params'] = $parameter;
+ while($timers[$timers['id']] || !$timers['id']) {
+ $timers['id']++;
+ if($timers['id'] > 9999999) $timers['id'] = 0;
+ }
+ $timers[$timers['id']] = $new;
+ return $timers['id'];
+}
+
+function kill_timer($id) {
+ global $timers;
+ unset($timers[$id]);
+}
+
+$timers['id']=0;
+
+?>
\ No newline at end of file
$ipv6 = array();
$ip = explode(":",$ip);
$last_zero = false; $zero_sequence = 0; $biggest_zero_sequence = 0; $max_start = -1;
- foreach($ip as $i => $v) {
+ $i = 0;
+ foreach($ip as $v) {
if($v == "") {
$skipBlocks = (8 - count($ip));
for($j = 0; $j < $skipBlocks; $j++) {
$ipv6[$i+$j] = "_";
}
$max_start = $i;
- $biggest_zero_sequence = $skipBlocks;
+ if($last_zero) {
+ $zero_sequence += $skipBlocks;
+ } else {
+ $last_zero = true;
+ $zero_sequence = $skipBlocks;
+ }
+ $i+=$skipBlocks;
+ if($zero_sequence > $biggest_zero_sequence) {
+ $biggest_zero_sequence = $zero_sequence;
+ $max_start = $i-($zero_sequence-1);
+ }
} else {
$value = hexdec($v);
if($value == 0) {
$ipv6[$i] = self::intToNum($value,3);
$last_zero = false;
}
+ $i++;
}
}
$ip = "";
"330" => "{num} 330 %s %s %s :is logged in as",
"318" => "{num} 318 %s %s :End of /WHOIS list.",
"401" => "{num} 401 %s %s :No such nick",
+ "SQ" => "{num} SQ :%s",
null => null
);
}
}
+ public function shutdown() {
+ if($this->client->connected()) {
+ if(($this->flags & self::FLAG_P10SESSION)) {
+ $this->send("SQ", "Shutdown requested.");
+ }
+ $this->client->disconnect();
+ }
+ }
+
public function setUplinkHost($host, $port, $ssl = false, $bind = null) {
$this->setSetting("host", $host);
$this->setSetting("port", $port);
$numeric = substr($this->server->getNumeric(),0,2).Numerics::intToNum($this->last_local_numeric, 3);
}
$this->last_local_numeric++;
+ $modes = new P10_UserModeSet($modes);
$user = new P10_User($nick, $numeric, $this->server, time(), $ident, $host, $ip, $realname, $modes);
if(($this->flags & self::FLAG_CONNECTED)) {
$ip = Numerics::numericFromIP($user->getIP());
}
}
- public function join($user, $chanName) {
+ public function join($user, $chanName, $privs = 0) {
if(!is_a($user, "P10_User") || !($user->getServer() === $this->server))
return ERR_INVALID_USER;
if($chanName[0] != "#")
$channel->joinUser($user);
if(($this->flags & self::FLAG_CONNECTED))
$this->send("J", $user->getNumeric(), $chanName, time(), 0);
+ if($privs != 0) {
+ $channel->setUserPrivs($user, $privs);
+ if(($this->flags & self::FLAG_CONNECTED)) {
+ $modestr = "+".(($privs & P10_Channel::USERPRIV_OPED) ? "o" : "").(($privs & P10_Channel::USERPRIV_VOICE) ? "v" : "");
+ $modestr .= (($privs & P10_Channel::USERPRIV_OPED) ? " ".$user->getNumeric() : "");
+ $modestr .= (($privs & P10_Channel::USERPRIV_VOICE) ? " ".$user->getNumeric() : "");
+ $this->send("OM", $user->getNumeric(), $chanName, $modestr);
+ }
+ }
if($this->eventHandler)
$this->eventHandler->event_join($user, $channel, false);
}
* initial php file
*
*/
+declare(ticks = 1);
+error_reporting(E_ALL & ~E_STRICT);
+
require_once("Uplink/Uplink.class.php");
require_once("ModCMD/ModCMD.class.php");
require_once("BotLoader/BotLoader.class.php");
+require_once("Tools/timer.inc.php");
+
+if(function_exists("pcntl_signal")) {
+ pcntl_signal(SIGINT, 'shutdown');
+ pcntl_signal(SIGTERM, 'shutdown');
+}
//basicly here is nothing, yet :D
$uplink = new Uplink();
$botloader = new BotLoader($uplink);
$botloader->loadBots();
+BotLoader::load("ModManager", "ModManager.class.php");
+
+function shutdown($signal) {
+ global $botloader;
+ global $uplink;
+ if($signal == SIGINT) $type="SIGINT";
+ else if($signal == SIGTERM) $type="SIGTERM";
+ else $type = $signal;
+ echo "\n\nrecived shutdown instruction... ".$type."\n";
+ $botloader->unloadBots();
+ $botloader->save();
+ $uplink->shutdown();
+ exit;
+}
while(true) {
$uplink->loop();
+ $botloader->loop();
+ timer_loop();
+ if(function_exists("pcntl_signal_dispatch"))
+ pcntl_signal_dispatch();
}
+
?>
\ No newline at end of file