Skip to content

Commit

Permalink
Command system rewritten
Browse files Browse the repository at this point in the history
  • Loading branch information
pBlueG committed May 21, 2016
1 parent 9ab1a5e commit 9ae65e4
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 253 deletions.
275 changes: 37 additions & 238 deletions classes/commandhandler.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
/**
* Commandhandler class
* - parses PRIVMSG data for commands
* - creates a table for commands and registers admin cmds:
* !join, !part, !quit, !addcmd, !delcmd, !load, !unload)
*
* @author BlueG
* @package mYsTeRy-v2
Expand All @@ -23,7 +21,6 @@ public function __construct()
$this->m_sTable = 'bot_commands';
$pDB = Database::getInstance();
if(!$pDB->_table_exists($this->m_sTable)) {
// the command table does not exist, therefore we will have to register all admin commands
$pDB->_create_table(
$this->m_sTable,
array(
Expand All @@ -34,219 +31,6 @@ public function __construct()
'privilege' => $pDB->_type('int', 2)
)
);
$this->_registerCommand(
'!join',
'if(count($aParams) < 1)
$bot->Say($sRecipient, "[b][color=red]Syntax:[/color][/b] !join (#channel) [key]");
else
if(isset($aParams[1]))
$bot->Join($aParams[0], $aParams[1]);
else
$bot->Join($aParams[0]);',
Privileges::LEVEL_BOT_ADMIN,
'Joins the given channel.'
);
$this->_registerCommand(
'!part',
'if(count($aParams) < 1)
$bot->Say($sRecipient, "[b][color=red]Syntax:[/color][/b] !part (#channel) [part message]");
else
if(isset($aParams[1]))
$bot->Part($aParams[0], $aParams[1]);
else
$bot->Part($aParams[0]);',
Privileges::LEVEL_BOT_ADMIN,
'Parts the given channel.'
);
$this->_registerCommand(
'!quit',
'if(is_array($aParams))
$bot->Quit(implode(" ", $aParams));
else
$bot->Quit();',
Privileges::LEVEL_BOT_ADMIN,
'Quits'
);
$this->_registerCommand(
'!!',
'if($bot->_isChild())
return;
if(is_array($aParams)) {
$sEval = implode(" ", $aParams);
ob_start();
eval($sEval);
$sReturn = ob_get_contents();
ob_end_flush();
$aReturn = array_filter(explode("\n", $sReturn));
foreach($aReturn as $sEcho)
$bot->Say($sRecipient, trim($sEcho));
} else {
$bot->Say($sRecipient, "[b][color=red]Syntax:[/color][/b] !! (code)");
}',
Privileges::LEVEL_BOT_ADMIN,
'Evaluates the given code as php.'
);
$this->_registerCommand(
'!addcmd',
'if($bot->_isChild())
return;
if(count($aParams) < 3) {
$bot->Say($sRecipient, "[b][color=red]Syntax:[/color][/b] !addcmd (command) (privilege) (phpcode)");
} else {
$cmd = CommandHandler::getInstance();
if($cmd->_commandExists($aParams[0])) {
$bot->Say($sRecipient, "[b][color=red]Error:[/color][/b] This command already exists.");
} else {
$code = trim(implode(" ", array_slice($aParams, 2)));
$aError = array();
if($cmd->_validateSyntax($code, $aError)) {
$cmd->_registerCommand($aParams[0], $code, $aParams[1]);
$bot->Say($sRecipient, "[b][color=green]Success:[/color][/b] The command [b]".$aParams[0]."[/b] has been succesfully added.");
} else {
$bot->Say($sRecipient, "[b][color=red]Error:[/color][/b] You have an error in your php syntax:");
foreach($aError as $sError)
$bot->Say($sRecipient, trim($sError));
}
}
}',
Privileges::LEVEL_BOT_ADMIN,
'Adds a command to the database.'
);
$this->_registerCommand(
'!delcmd',
'if($bot->_isChild())
return;
if(count($aParams) < 1) {
$bot->Say($sRecipient, "[b][color=red]Syntax:[/color][/b] !delcmd (command)");
} else {
$cmd = CommandHandler::getInstance();
if($cmd->_unregisterCommand($aParams[0], true))
$bot->Say($sRecipient, "[b][color=green]Success:[/color][/b] The command has been successfully removed.");
else
$bot->Say($sRecipient, "[b][color=red]Error:[/color][/b] This command does not exists.");
unset($cmd);
}',
Privileges::LEVEL_BOT_ADMIN,
'Deletes a command from the database.'
);
$this->_registerCommand(
'!cmds',
'if($bot->_isChild() || !Misc::isChannel($sRecipient))
return;
if(Privileges::IsBotAdmin($sIdent))
$priv = Privileges::LEVEL_BOT_ADMIN;
else
$priv = Privileges::GetUserPrivilege($sUser, $sRecipient);
$sCmds = CommandHandler::getInstance()->_listCommands($priv);
$bot->Notice($sUser, "Commands: ".$sCmds);',
Privileges::LEVEL_NONE,
'Displays all registered commands.'
);
$this->_registerCommand(
'!load',
'if($bot->_isChild())
return;
if(count($aParams) < 1) {
$bot->Say($sRecipient, "[b][color=red]Syntax:[/color][/b] !load (plugin name)");
} else {
$ptr = Plugins::getInstance();
$sPlugin = $aParams[0];
if($ptr->_plugin_exists($sPlugin)) {
if(!$ptr->_isLoaded($sPlugin)) {
$sError = NULL;
try {
$ptr->_load($sPlugin);
} catch (Exception $e) {
$sError = $e->getMessage();
$sError = str_replace(array("\n", "\r", "\t"), "", $sError);
}
if(is_null($sError))
$bot->Say($sRecipient, "[b][color=green]Success:[/color][/b] The plugin `".$sPlugin."` has been successfully loaded.");
else {
$bot->Say($sRecipient, "[b][color=red]Error:[/color][/b] An error has occured:");
$bot->Say($sRecipient, $sError);
}
} else {
$bot->Say($sRecipient, "[b][color=red]Error:[/color][/b] This plugin is already loaded. Use !unload ".$sPlugin.".");
}
} else {
$bot->Say($sRecipient, "[b][color=red]Error:[/color][/b] `".$sPlugin."` does not exist.");
}
unset($ptr);
}',
Privileges::LEVEL_BOT_ADMIN,
'Loads a plugin.'
);
$this->_registerCommand(
'!unload',
'if($bot->_isChild())
return;
if(count($aParams) < 1) {
$bot->Say($sRecipient, "[b][color=red]Syntax:[/color][/b] !unload (plugin name)");
} else {
$ptr = Plugins::getInstance();
$sPlugin = $aParams[0];
if($ptr->_unload($sPlugin))
$bot->Say($sRecipient, "[b][color=green]Success:[/color][/b] `".$sPlugin."` has been successfully unloaded.");
else
$bot->Say($sRecipient, "[b][color=red]Error:[/color][/b] `".$sPlugin."` is not loaded.");
unset($ptr);
}',
Privileges::LEVEL_BOT_ADMIN,
'Unloads a plugin.'
);
$this->_registerCommand(
'!plugins',
'if($bot->_isChild())
return;
$sPlugins = NULL;
$ptr = Plugins::getInstance();
reset($ptr->m_aPlugins);
while(current($ptr->m_aPlugins)) {
$sPlugins .= key($ptr->m_aPlugins). ".class.php, ";
next($ptr->m_aPlugins);
}
reset($ptr->m_aPlugins);
$sPlugins = substr($sPlugins, 0, -2);
$bot->Say(
$sRecipient,
"[b]Active plugin instances:[/b] ".$sPlugins
);',
Privileges::LEVEL_BOT_ADMIN,
'Displays all active plugins.'
);
$this->_registerCommand(
'!ident',
'if($bot->_isChild())
return;
$bot->Notice(
$sUser,
"Your ident is ".$sIdent
);',
Privileges::LEVEL_NONE,
'Shows the ident.'
);
$this->_registerCommand(
'!mem',
'if($bot->_isChild())
return;
$bot->Say(
$sRecipient,
"Current memory usage is [b]".Misc::formatBytes(memory_get_usage(), "MB")."[/b]"
);',
Privileges::LEVEL_BOT_ADMIN,
'Displays the current memory usage allocated by mYsTeRy.'
);
$this->_registerCommand(
'!uptime',
'$sUptime = time() - $bot->m_aPing["Uptime"];
$bot->PM(
$sRecipient,
"I have been up for ".Misc::SecondsToString($sUptime)
);',
Privileges::LEVEL_BOT_ADMIN,
'Displays the current memory usage allocated by mYsTeRy.'
);
} else {
$this->_loadCommands();
}
Expand Down Expand Up @@ -295,39 +79,46 @@ private function _getPermission($privilege)
return $iPermission;
}

public function _registerCallback($sCommand, $oClass, $sCallback, $privilege)
public function _registerCommand($sCommand, $mixed, $sCallback, $privilege, $description)
{
if(!$this->_commandExists($sCommand)) {
if(method_exists($oClass, $sCallback) && is_callable(array($oClass, $sCallback))) {
if(is_object($mixed)) {
if(method_exists($mixed, $sCallback) && is_callable(array($mixed, $sCallback))) {
$this->m_aCommands[] = array(
'command' => $sCommand,
'code' => NULL,
'description' => $description,
'privilege' => $this->_getPermission($privilege),
'class' => $mixed,
'callback' => $sCallback
);
return $this;
}
} else {
$sCode = str_replace(array("\r", "\n", "\t"), "", $mixed);
$this->m_aCommands[] = array(
'command' => $sCommand,
'code' => NULL,
'class' => $oClass,
'callback' => $sCallback,
'command' => $sCommand,
'code' => $sCode,
'description' => $description,
'privilege' => $this->_getPermission($privilege)
);
return true;
end($this->m_aCommands);
$func = debug_backtrace();
if(strcmp($func[1]['function'], '_saveCommand') !== 0)
$this->_addClosure($mixed);
}

}
return false;
}

public function _registerCommand($sCommand, $sCode, $privilege, $description = NULL, $save_to_db = true)
public function _saveCommand($sCommand, $sCode, $privilege, $description = NULL)
{
if(!$this->_commandExists($sCommand)) {
$finalCode = str_replace(array("\r", "\n", "\t"), "", $sCode);
$closure = create_function('$bot, $sCommand, $aParams, $sUser, $sRecipient, $sIdent', $finalCode);
$this->m_aCommands[] = array(
'command' => $sCommand,
'code' => $finalCode,
'description' => $description,
'privilege' => $this->_getPermission($privilege)
);
end($this->m_aCommands);
$this->_registerCommand($sCommand, $sCode, NULL, $privilege, $description);
$ret = key($this->m_aCommands);
if($save_to_db)
Database::getInstance()->_insert($this->m_sTable, $this->m_aCommands[$ret]);
$this->m_aCommands[$ret]['closure'] = $closure;
Database::getInstance()->_insert($this->m_sTable, $this->m_aCommands[$ret]);
$this->_addClosure($sCode, $ret);
return true;
}
return false;
Expand All @@ -344,6 +135,14 @@ public function _unregisterCommand($sCommand, $db_reset = false)
Database::getInstance()->_delete($this->m_sTable, array('command' => $sCommand));
return true;
}

private function _addClosure($sCode, $key = NULL)
{
$closure = create_function('$bot, $sCommand, $aParams, $sUser, $sRecipient, $sIdent', $sCode);
if(is_null($key))
$key = key($this->m_aCommands);
$this->m_aCommands[$key]['closure'] = $closure;
}

public function _parse($bot, $sCommand, $aParams, $sUser, $sRecipient, $sIdent)
{
Expand Down Expand Up @@ -378,7 +177,7 @@ public function _parse($bot, $sCommand, $aParams, $sUser, $sRecipient, $sIdent)
$bExists = true;
if($bExecute || !$RequiredPrivilege || $bIsAdmin) {
if(array_key_exists('callback', $aCommand))
call_user_func_array(array($aCommand['class'], $aCommand['callback']), array($bot, $sUser, $sRecipient, $aParams));
call_user_func_array(array($aCommand['class'], $aCommand['callback']), array($bot, $sUser, $sRecipient, $aParams, $sIdent));
else
//$aCommand['closure']($bot, $sCommand, $aParams, $sUser, $sRecipient, $sIdent);
call_user_func($aCommand['closure'], $bot, $sCommand, $aParams, $sUser, $sRecipient, $sIdent);
Expand All @@ -396,7 +195,7 @@ private function _loadCommands()
$pDB = Database::getInstance();
$result = $pDB->_query('SELECT `command`, `code`, `description`, `privilege` FROM `'.$this->m_sTable.'`');
while($row = $pDB->_fetch_array($result)) {
$this->_registerCommand($row['command'], $row['code'], $row['privilege'], $row['description'], false);
$this->_registerCommand($row['command'], $row['code'], NULL, $row['privilege'], $row['description'], false);
}
unset($pDB);
unset($result);
Expand Down
2 changes: 1 addition & 1 deletion classes/socket.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public function _getValidServer(array $server)
* @param string $server
* @return boolean
*/
public function _checkServer($server)
private function _checkServer($server)
{
$IP = gethostbyname($server);
if(@filter_var($IP, FILTER_VALIDATE_IP) !== FALSE)
Expand Down
47 changes: 33 additions & 14 deletions configuration/general.ini
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
[General]
SQLite = on ;
MySQL = off ; see mysql.ini for host/user/db config
AdminPass = changethis ; specifies the password to get recognised as bot admin -> /msg BotNickname login password
Admins[] = "[email protected]" ; adding your ident allows you to get recognised as administrator without login
;Admins[] = "[email protected]" ; format: nickname!ident@hostname
Logging = on ; specifies whether all channel messages get logged
Sleep = 40000 ; specifies the sleep time of the bot (in micro seconds)
Prefix = "!" ; command prefix
Ping = 60 ; specifies the bot ping timeout check in seconds
;Plugins[] = test ; plugins loaded on startup, use !load/!unload when the bot is connected
Plugins[] = ctcp
Plugins[] = dcc
; SQLite : on/off
SQLite = on

; MySQL : on/off
; @ /configuration/mysql.ini
MySQL = off

; AdminPass : specifies the password of the bot
; How to log in on IRC: /msg BotNickname login [password]
AdminPass = changethis

; Admins[] : defines who is allowed to fully control the bot without logging in
; Format nickname!ident@hostname
Admins[] = "[email protected]"

; Sleep : specified the sleep time of the bot in micro seconds
Sleep = 40000

; Prefix : sets the command prefix
Prefix = "!"

; Ping : sets the ping timeout check in seconds
Ping = 60

; Plugins[] : defines what plugins are being initialized on startup (/plugins/)
Plugins[] = "ctcp"
Plugins[] = "dcc"
Plugins[] = "auto_perform"
Plugins[] = "channel_log"
BindIP = ; specifies the IP & port that PHP will use to access the network
; e.g. "192.168.0.1:1001"
Plugins[] = "commands"

; BindIP : specifies the IP & port that PHP will use to access the network
; e.g. "192.168.0.1:1001"
BindIP =

0 comments on commit 9ae65e4

Please sign in to comment.