/** * Handles commands. * * @param \Mars\Network\Server $server The server instance. * @param \Mars\Message\Message $message The message instance. * * @return false|void */ protected function _handleQuery(Server $server, $message) { //Verify required information. if (count($message->arguments) < $this->_commands[$message->command]['params']) { //Check if the user has given enough parameters. $server->ModuleManager->message('Not enough parameters given. Syntax: ' . $this->_commands[$message->command]['syntax']); return false; } //Handle the command. switch ($message->command) { case 'say': $server->ModuleManager->message($message->parts[1]); break; case 'info': $server->ModuleManager->message('I am developed with the Mars Framework.(https://github.com/Xety/MarsBot) The developer is : Mars(1000069).'); break; case 'version': $server->ModuleManager->message('The current version is : ' . Configure::version()); break; case 'time': $seconds = floor(microtime(true) - TIME_START); $start = new \DateTime("@0"); $end = new \DateTime("@{$seconds}"); $server->ModuleManager->message('I\'m running since ' . $start->diff($end)->format('%a days, %h hours, %i minutes and %s seconds.')); break; } }
/** * Constructor. * * Set up the configuration. */ public function __construct() { $this->_configCommands = Configure::read('Commands'); $this->_botAdmins = Configure::read('Bot.admin'); //List of commands and arguments needed. You must put the name of the command in lowercase. $commands = ['room' => ['params' => 2, 'syntax' => $this->_configCommands['prefix'] . 'Room [Go] [RoomName]'], 'chat' => ['params' => 1, 'syntax' => $this->_configCommands['prefix'] . 'Chat [Info] Optional : [Group Power Name]']]; $this->_commands = $commands; }
/** * Constructor. * * Set up the configuration. */ public function __construct() { $this->_configCommands = Configure::read('Commands'); $this->_botAdmins = Configure::read('Bot.admin'); //List of commands and arguments needed. You must put the name of the command in lowercase. $commands = ['user' => ['params' => 1, 'syntax' => $this->_configCommands['prefix'] . 'User [Time|Loaded|Count] Optional : [UserId]']]; $this->_commands = $commands; }
/** * Save a xavi for the bot. * * @param string $xavi The xavi to save. * @param array $infos The informations needed to save the xavi. * * @return bool */ public static function post($xavi, $infos = []) { $http = new Http(); $http->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $response = $http->post('http://xat.com/json/xavi/put.php', ['s' => 60, 'au' => 'undefined', 't' => $infos['y']['t'], 'j' => 'undefined', 'u' => Configure::read('Bot.id'), 'k' => $infos['y']['I'], 'v' => 'undefined', 'i' => $infos['y']['i'], 'xavi' => $xavi]); if ($response->isOk() && $response->getBody() == "OK") { return true; } return false; }
/** * Prints out debug information about given variable. * * Only runs if debug level is greater than zero. * * @param mixed $var Variable to show debug information for. * * @return void */ function debug($var) { if (!Configure::read('debug')) { return; } $trace = Debugger::trace(['start' => 1, 'depth' => 2, 'format' => 'array']); $search = [ROOT]; $file = str_replace($search, '', $trace[0]['file']); $line = $trace[0]['line']; $lineInfo = sprintf('%s (line %s)', $file, $line); $template = <<<TEXT %s ########## DEBUG ########## %s ########################### %s TEXT; $var = Debugger::exportVar($var, 25); printf($template, $lineInfo, $var, PHP_EOL); }
/** * The bot has enter in the room and has got all the packet. * * @param \Mars\Network\Server $server The server instance. * @param array $data The data received from the socket. * * @return bool */ public function onDone(Server $server, $data) { if (Configure::read('Xavi.enabled') === true) { if (!is_numeric(Configure::read('Xavi.id'))) { return false; } $xavi = Xavi::get(Configure::read('Xavi.id')); if ($xavi === false) { $server->ModuleManager->message('Error to get the xavi of the user ' . Configure::read('Xavi.id')); return false; } $result = Xavi::post($xavi, $server->Room->loginInfos); if ($result === false) { $server->ModuleManager->message('Error to save the xavi.'); return false; } $server->ModuleManager->message('My xavi has been saved successfully with the MarsBot ! Thanks to Mars. :)'); $server->Socket->disconnect(); return true; } return false; }
/** * Configure paths required to find general filepath constants. */ require __DIR__ . DIRECTORY_SEPARATOR . 'paths.php'; // Use composer to load the autoloader. require ROOT . DS . 'vendor' . DS . 'autoload.php'; require APP . 'basics.php'; use Mars\Configure\Configure; /** * Read configuration file and inject configuration into various * Mars classes. * * By default there is only one configuration file. It is often a good * idea to create multiple configuration files, and separate the configuration * that changes from configuration that does not. This makes deployment simpler. */ try { Configure::load('config'); } catch (\Exception $e) { die($e->getMessage() . "\n"); } /** * Set server timezone to UTC. You can change it to another timezone of your * choice but using UTC makes time calculations / conversions easier. */ date_default_timezone_set('UTC'); /** * Set time limit to unlimited or the script will ended itself. */ set_time_limit(0);
/** * Build the private packet to send it in the socket. * * @return string */ protected function _buildPrivatePacket() { $packet = ['v' => ['n' => Configure::read('Bot.username'), 'p' => Configure::read('Bot.password')]]; return Xml::build($packet); }
/** * Handle the module command. * * @param \Mars\Network\Server $server The server instance. * @param \Mars\Message\Message $message The message instance. * * @return bool|void */ protected function _handleModule(Server $server, $message) { if (!isset($message->arguments[1]) && $message->arguments[0] != 'loaded') { $server->ModuleManager->message('Not enough parameters given. Syntax: ' . $this->_commands[$message->command]['syntax']); return false; } switch ($message->arguments[0]) { case 'load': //Load the Module. $module = $server->ModuleManager->load($message->arguments[1]); switch ($module) { //AlreadyLoaded case 'AL': $server->ModuleManager->message('The Module [' . $message->arguments[1] . '] is already loaded.'); break; //Loaded //Loaded case 'L': $server->ModuleManager->message('Module [' . $message->arguments[1] . '] loaded successfully.'); break; //NotFound //NotFound case 'NF': $server->ModuleManager->message('The Module [' . $message->arguments[1] . '] was not found.'); break; } break; case 'unload': //Prevent for loading a file in the memory for nothing. if (Configure::read('debug') === false) { $server->ModuleManager->message('You can\'t unload a Module when the debug is false.'); break; } //Unload the Module. $module = $server->ModuleManager->unload($message->arguments[1]); //AlreadyUnloaded if ($module === 'AU') { $server->ModuleManager->message('The Module [' . $message->arguments[1] . '] is already unloaded or doesn\'t exist.'); } else { $server->ModuleManager->message('Module [' . $message->arguments[1] . '] unloaded successfully.'); } break; case 'reload': //Prevent for loading a file in the memory for nothing. if (Configure::read('debug') === false) { $server->ModuleManager->message('You can\'t reload a Module when the debug is false.'); break; } //Check if we must reload all Modules. if ($message->arguments[1] == "all") { //Get the list of the loaded Modules. $loadedModules = $server->ModuleManager->getLoadedModules(); //For each Modules, we reload it. foreach ($loadedModules as $module) { $this->_reloadModule($server, $module); //To avoid spam. usleep(500000); } break; } //Else there is just one Module to reload. $this->_reloadModule($server, $message->arguments[1]); break; case 'time': //Get the UNIX time. $time = $server->ModuleManager->timeLoaded($message->arguments[1]); //If $time is false, that mean the Module is not loaded and/or doesn't exist. if ($time === false) { $server->ModuleManager->message('This Module is not loaded.'); break; } $server->ModuleManager->message('The Module is loaded since : ' . date("H:i:s d/m/Y", $time) . '.'); break; case 'loaded': //Get the loaded Modules and implode the array as a string. $modules = $server->ModuleManager->getLoadedModules(); $modules = implode(", ", $modules); $server->ModuleManager->message('Modules loaded : ' . $modules . '.'); break; default: $server->ModuleManager->message('Unknown command. Syntax: ' . $this->_commands[$message->command]['syntax']); } }
/** * Connect the bot to a room. * * @param string|int $room The room to join. * @param string $host The host to connect to the room. * @param int $port The port used to connect to the room. * * @return void */ public function connect($room = null, $host = null, $port = null) { if (is_null($room)) { $room = Configure::read('Room.name'); } $room = Room::getRoomInfo($room); $array = $this->Room->join($this->Network->loginInfos, $room, $host, $port); $this->Socket = $array['socket']; $this->Network->loginInfos = $array['network']; $this->ModuleManager->addPrefixArgument($this); $this->PacketManager->addPrefixArgument($this); //Handle the loop. $this->_handleWhile(); }
/** * Get information about the Gcontrol power. * * @param array $roomInfo An array of the Gcontrol configuration. * * @return false|string */ protected static function _getGcontrolInfo($roomInfo) { if (!is_array($roomInfo)) { return false; } $phrase = 'Gcontrol info : '; $rank = isset($roomInfo['mg']) ? static::$_rankValue[(int) $roomInfo['mg']] : static::$_rankValue[7]; $phrase .= ' Make Guest : ' . $rank; $type = isset($roomInfo['mb']) ? static::$_rankValue[(int) $roomInfo['mb']] : static::$_rankValue[8]; $phrase .= ' Make Member : ' . $type; $type = isset($roomInfo['mm']) ? static::$_rankValue[(int) $roomInfo['mm']] : static::$_rankValue[11]; $phrase .= ' Make Moderator : ' . $type; $type = isset($roomInfo['kk']) ? static::$_rankValue[(int) $roomInfo['kk']] : static::$_rankValue[7]; $phrase .= ' Kick : ' . $type; $type = isset($roomInfo['bn']) ? static::$_rankValue[(int) $roomInfo['bn']] : static::$_rankValue[7]; $phrase .= ' Ban : ' . $type; $type = isset($roomInfo['ubn']) ? static::$_rankValue[(int) $roomInfo['ubn']] : static::$_rankValue[7]; $phrase .= ' Unban : ' . $type; $type = isset($roomInfo['mbt']) ? $roomInfo['mbt'] : '6'; $phrase .= ' Mod Max Ban Time : ' . $type; $type = isset($roomInfo['obt']) ? (int) $roomInfo['obt'] === 0 ? 'Forever' : $roomInfo['obt'] : 'Forever'; $phrase .= ' Owner Max Ban Time : ' . $type; $type = isset($roomInfo['ss']) ? static::$_rankValue[(int) $roomInfo['ss']] : static::$_rankValue[10]; $phrase .= ' Set Scroller : ' . $type; $type = isset($roomInfo['lkd']) ? static::$_rankValue[(int) $roomInfo['lkd']] : static::$_rankValue[0]; $phrase .= ' Must be Locked : ' . $type; $type = isset($roomInfo['rgd']) ? static::$_rankValue[(int) $roomInfo['rgd']] : static::$_rankValue[0]; $phrase .= ' Must be Registered : ' . $type; $type = isset($roomInfo['bst']) ? $roomInfo['bst'] : '0'; $phrase .= ' Preferred Blast : ' . $type; $type = isset($roomInfo['prm']) ? static::$_rankValue[(int) $roomInfo['prm']] : static::$_rankValue[5]; $phrase .= ' Can Promote : ' . $type; $type = isset($roomInfo['bge']) ? static::$_rankValue[(int) $roomInfo['bge']] : static::$_rankValue[7]; $phrase .= ' Barge In : ' . $type; $type = isset($roomInfo['mxt']) ? $roomInfo['mxt'] : '10'; $phrase .= ' Max Toons : ' . $type; $type = isset($roomInfo['ads']) ? $roomInfo['ads'] : '0'; $phrase .= ' Ads Position : ' . $type; $type = isset($roomInfo['sme']) ? static::$_rankValue[(int) $roomInfo['sme']] : static::$_rankValue[7]; $phrase .= ' Silent Member : ' . $type; $type = isset($roomInfo['dnc']) ? static::$_rankValue[(int) $roomInfo['dnc']] : static::$_rankValue[14]; $phrase .= ' Can be Dunced : ' . $type; $type = isset($roomInfo['bdg']) ? static::$_rankValue[(int) $roomInfo['bdg']] : static::$_rankValue[10]; $phrase .= ' Can Award Badge : ' . $type; $type = isset($roomInfo['ns']) ? static::$_rankValue[(int) $roomInfo['ns']] : static::$_rankValue[7]; $phrase .= ' Can Naughty Step : ' . $type; $type = isset($roomInfo['yl']) ? static::$_rankValue[(int) $roomInfo['yl']] : static::$_rankValue[7]; $phrase .= ' Can Yellow Card : ' . $type; $type = isset($roomInfo['p']) ? static::$_rankValue[(int) $roomInfo['p']] : static::$_rankValue[10]; $phrase .= ' Protect Mode : ' . $type; $type = isset($roomInfo['pd']) ? $roomInfo['pd'] : '1'; $phrase .= ' Protect Default : ' . $type; $type = isset($roomInfo['pt']) ? $roomInfo['pt'] : '1'; $phrase .= ' Protect Time (hours) : ' . $type; $type = isset($roomInfo['ka']) ? static::$_rankValue[(int) $roomInfo['ka']] : static::$_rankValue[10]; $phrase .= ' Kick All : ' . $type; $type = isset($roomInfo['mft']) ? $roomInfo['mft'] : '4'; $phrase .= ' Member Flood Trust : ' . $type; $type = isset($roomInfo['ft']) ? $roomInfo['ft'] : '50'; $phrase .= ' Flood Threshold : ' . $type; $http = new Http(); $response = $http->post('http://pastebin.com/api/api_post.php', ['api_option' => 'paste', 'api_dev_key' => Configure::read('Pastebin.apiDevKey'), 'api_user_key' => '', 'api_paste_private' => Configure::read('Pastebin.apiPastePrivate'), 'api_paste_expire_date' => Configure::read('Pastebin.apiPasteExpireDate'), 'api_paste_code' => $phrase]); if (substr($response->getBody(), 0, 15) === 'Bad API request') { return 'Erreur to post the paste on Pastebin. Error : ' . $response->body; } $phrase = 'Gcontrol info : ' . $response->body; return $phrase; }
/** * Get information about the sserver. * * @return string */ protected function _getServerInfo() { if (stristr(PHP_OS, 'win')) { $wmi = new \COM("Winmgmts://"); $processor = $wmi->execquery("SELECT Name FROM Win32_Processor"); $physicalMemory = $wmi->execquery("SELECT Capacity FROM Win32_PhysicalMemory"); $baseBoard = $wmi->execquery("SELECT * FROM Win32_BaseBoard"); $threads = $wmi->execquery("SELECT * FROM Win32_Process"); $disks = $wmi->execquery("SELECT * FROM Win32_DiskQuota"); foreach ($processor as $wmiProcessor) { $name = $wmiProcessor->Name; } $memory = 0; foreach ($physicalMemory as $wmiPhysicalMemory) { $memory += $wmiPhysicalMemory->Capacity; } $memoryMo = $memory / 1024 / 1024; $memoryGo = $memoryMo / 1024; foreach ($baseBoard as $wmiBaseBoard) { $boardName = $wmiBaseBoard->Product; $boardName .= ' ' . $wmiBaseBoard->Manufacturer; } $phrase = 'Server Information : '; $phrase .= ' Processor : ' . $name; $phrase .= ' Memory : ' . round($memoryMo, 2) . 'Mo (' . round($memoryGo, 2) . 'Go)'; $phrase .= ' MotherBoard : ' . $boardName; $phrase .= ' Threads Information :'; $threadsCount = 0; $totalMemoryUsed = 0; foreach ($threads as $thread) { $phrase .= ' Name : ' . $thread->Name; $phrase .= ' Threads Count : ' . $thread->ThreadCount; $totalMemoryUsed += $thread->WorkingSetSize / 1024 / 1024; $memoryKo = $thread->WorkingSetSize / 1024; $memoryMo = $memoryKo / 1024; $phrase .= ' Memory used : ' . round($memoryKo, 2) . 'Ko (' . round($memoryMo, 2) . 'Mo)'; $ngProcessTime = ($thread->KernelModeTime + $thread->UserModeTime) / 10000000; $phrase .= ' Processor used by the process : ' . round($ngProcessTime, 2); $phrase .= ' ProcessID : ' . $thread->ProcessID . ' '; $threadsCount += $thread->ThreadCount; } $phrase .= ' Total Memory Used : ' . round($totalMemoryUsed, 2) . 'Mo' . '(' . round($totalMemoryUsed / 1024, 2) . 'Go)'; $phrase .= ' Total Threads Count : ' . $threadsCount . ' threads'; $http = new Http(); $response = $http->post('http://pastebin.com/api/api_post.php', ['api_option' => 'paste', 'api_dev_key' => Configure::read('Pastebin.apiDevKey'), 'api_user_key' => '', 'api_paste_private' => Configure::read('Pastebin.apiPastePrivate'), 'api_paste_expire_date' => Configure::read('Pastebin.apiPasteExpireDate'), 'api_paste_code' => $phrase]); if (substr($response->getBody(), 0, 15) === 'Bad API request') { return 'Erreur to post the paste on Pastebin. Error : ' . $response->body; } $phrase = 'Server info : ' . $response->body; return $phrase; } elseif (PHP_OS == 'Linux') { $version = explode('.', PHP_VERSION); $phrase = 'PHP Version : ' . $version[0] . '.' . $version[1]; // File that has it $file = '/proc/cpuinfo'; // Not there? if (!is_file($file) || !is_readable($file)) { return 'Unknown'; } // Get contents $contents = trim(file_get_contents($file)); // Lines $lines = explode("\n", $contents); // Holder for current CPU info $cpu = []; // Go through lines in file $numLines = count($lines); for ($i = 0; $i < $numLines; $i++) { $line = explode(':', $lines[$i], 2); if (!array_key_exists(1, $line)) { continue; } $key = trim($line[0]); $value = trim($line[1]); // What we want are MHZ, Vendor, and Model. switch ($key) { // CPU model case 'model name': case 'cpu': case 'Processor': $cpu['Model'] = $value; break; // Speed in MHz // Speed in MHz case 'cpu MHz': $cpu['MHz'] = $value; break; case 'Cpu0ClkTck': // Old sun boxes $cpu['MHz'] = hexdec($value) / 1000000; break; // Brand/vendor // Brand/vendor case 'vendor_id': $cpu['Vendor'] = $value; break; // CPU Cores // CPU Cores case 'cpu cores': $cpu['Cores'] = $value; break; } } $phrase .= " Processor : " . $cpu['Model']; return $phrase; } else { return 'This function work only on a Windows system. :('; } }
/** * Loads a module into the Framework and prioritize it according to our priority list. * * @param string $module Filename in the MODULE_DIR we want to load. * * @throws \RuntimeException When the class doesn't implement the ModuleInterface. * * @return string */ public function load($module) { $module = Inflector::camelize($module); if (isset($this->_loadedModules[$module])) { //Return the message AlreadyLoaded. return 'AL'; } elseif (!file_exists(MODULE_DIR . DS . $module . '.php')) { debug('Class file for ' . $module . ' could not be found.'); //Return NotFound. return 'NF'; } //Check if this class already exists. $path = MODULE_DIR . DS . $module . '.php'; $className = Configure::read('App.namespace') . DS . 'Module' . DS . 'Module' . DS . $module; if (Configure::read('debug') === false) { require_once $path; } else { //Here, we load the file's contents first, then use preg_replace() to replace the original class-name with a random one. //After that, we create a copy and include it. $newClass = $module . '_' . md5(mt_rand() . time()); $contents = preg_replace("/(class[\\s]+?)" . $module . "([\\s]+?implements[\\s]+?ModuleInterface[\\s]+?{)/", "\\1" . $newClass . "\\2", file_get_contents($path)); $name = tempnam(TMP_MODULE_DIR, $module . '_'); file_put_contents($name, $contents); require_once $name; unlink($name); $className = Configure::read('App.namespace') . DS . 'Module' . DS . 'Module' . DS . $newClass; } $className = str_replace('/', '\\', rtrim($className, '\\')); $objectModule = new $className(); $new = ['object' => $objectModule, 'loaded' => time(), 'name' => $className, 'modified' => isset($contents) ? true : false]; //Check if this module implements our default interface. if (!$objectModule instanceof ModuleInterface) { throw new \RuntimeException(sprintf('ModuleManager::load() expects "%s" to be an instance of ModuleInterface.', $className)); } //Prioritize. if (in_array($module, $this->_priorityList)) { //So, here we reverse our list of loaded modules, so that prioritized modules will be the last ones, //then, we add the current prioritized modules to the array and reverse it again. $temp = array_reverse($this->_loadedModules, true); $temp[$module] = $new; $this->_loadedModules = array_reverse($temp, true); } else { $this->_loadedModules[$module] = $new; } //Return the message Loaded. return 'L'; }
/** * When an user tickle the bot, you must send back this packet to display * the bot's powers and others information about the bot. * * @param \Mars\Network\Server $server The server instance. * @param int $id The user id. * * @return bool */ public function answerTickle(Server $server, $id) { $server->Socket->write(Xml::build(['z' => ['d' => $id, 'u' => Configure::read('Bot.id') . '_0', 't' => '/a_NF']])); return true; }
/** * Build the join packet (J2). * * - Order attributes : * cb,Y,l5,l4,l3,l2,q,y,k,k3,d1,z,p,c,b,r,f,e,u,m,d0,d[i],dO,sn,dx,dt,N,n,a,h,v * * @param array $connection The connection array. * @param array $network The login array. * @param int $room The room id. * * @return string The packet generated. * * @throws \Mars\Network\Exception\RoomException When the $connection and/or $network variables are empty. */ protected function _buildJoinPacket(array $connection = [], array $network = [], $room = null) { if (empty($connection) || empty($network)) { throw new RoomException('The connection and/or network variable(s) can not be empty to build the J2 packet.', E_WARNING); } if (is_null($room)) { $room = $this->config()['room']; } $j2 = ['j2' => ['cb' => $connection['y']['c']]]; if (isset($connection['y']['au'])) { $j2['j2']['Y'] = 2; } $j2['j2'] += ['l5' => '65535', 'l4' => rand(10, 500), 'l3' => rand(10, 500), 'l2' => 0, 'q' => 1, 'y' => $connection['y']['i'], 'k' => $network['v']['k1'], 'k3' => $network['v']['k3']]; if (isset($network['v']['d1'])) { $j2['j2']['d1'] = $network['v']['d1']; } $j2['j2'] += ['z' => 12, 'p' => 0, 'c' => $room, 'r' => '', 'f' => 0, 'e' => 1, 'u' => $network['v']['i'], 'd0' => $network['v']['d0']]; for ($x = 2; $x <= 15; $x++) { if (isset($network['v']['d' . $x])) { $j2['j2']['d' . $x] = $network['v']['d' . $x]; } } if (isset($network['v']['dO'])) { $j2['j2']['dO'] = $network['v']['dO']; } if (isset($network['v']['dx'])) { $j2['j2']['dx'] = $network['v']['dx']; } if (isset($network['v']['dt'])) { $j2['j2']['dt'] = $network['v']['dt']; } $j2['j2'] += ['N' => $network['v']['n'], 'n' => Configure::read('Bot.name'), 'a' => Configure::read('Bot.avatar'), 'h' => Configure::read('Bot.home'), 'v' => 0]; return Xml::build($j2); }